17  17. Creating, Copying, Moving, and Deleting

So far you have only looked around. This page covers the commands that change things: mkdir and touch create, cp copies, mv moves and renames, and rmdir and rm delete. You will practice in a new folder called playground inside the practice files, and delete it at the end.

As on the previous page, the outputs come from Maria’s Mac (with her practice files in ~/Documents/bash-tutorial-files). Where Git Bash words an error message differently, both versions are shown.

17.1 Set up a playground

cd ~/Documents/bash-tutorial-files
mkdir playground
cd playground

Experimenting in a throwaway folder is a good habit: if something goes wrong, nothing important is affected.

17.2 Creating folders: mkdir

mkdir (make directory) creates one or more folders. With the -p option (parents), it also creates any missing folders along the path:

mkdir reports
mkdir -p archive/2026/october
ls -F

Output:

archive/        reports/
ls archive/2026

Output:

october

Without -p, mkdir refuses to create a folder inside a folder that doesn’t exist yet. It also refuses to create a folder that already exists:

$ mkdir backups/2026
mkdir: backups: No such file or directory
$ mkdir reports
mkdir: reports: File exists

Git Bash words these as mkdir: cannot create directory followed by the name and the same reason. mkdir -p never complains about a folder that already exists.

17.3 Creating empty files: touch

touch creates an empty file - or several at once. If a file already exists, touch leaves its contents alone and only updates its “last modified” time.

touch todo.txt notes.txt
ls

Output:

archive         notes.txt       reports         todo.txt

Usually you create files with an editor or a program; touch is just a quick way to make an empty one. To put text into a file from the command line, see Writing to Files: echo, >, >>, and cat.

17.4 Copying: cp

cp source destination copies a file. The destination can be a new name, or an existing folder (then the copy keeps its name):

cp todo.txt todo-backup.txt
cp ../documents/notes/ideas.txt .
ls

Output:

archive         notes.txt       todo-backup.txt
ideas.txt       reports         todo.txt

The first command makes a copy with a new name. The second copies ideas.txt from the practice files into . - the current folder.

To copy a folder and everything in it, add -r (recursive: “and everything inside, all the way down”):

cp -r ../projects/website website-copy
ls website-copy

Output:

index.html      styles.css

Without -r, cp refuses to copy a folder:

$ cp ../projects/website website-copy
cp: ../projects/website is a directory (not copied).

(Git Bash: cp: -r not specified; omitting directory '../projects/website'.)

cp and mv overwrite without asking

If a file with the destination name already exists, cp and mv replace it silently - its old contents are gone. Add -i (interactive) to be asked first, for example cp -i todo.txt notes.txt. Answer y to overwrite or n to keep the existing file.

17.5 Moving and renaming: mv

mv (move) does two jobs, because moving and renaming are really the same operation: giving a file a new path (a new folder, a new name, or both). Unlike cp, it moves folders without needing -r.

mv todo-backup.txt old-todo.txt
mv old-todo.txt archive
mv notes.txt archive/2026/october/october-notes.txt
mv website-copy archive
ls -F

Output:

archive/        ideas.txt       reports/        todo.txt
ls -F archive

Output:

2026/           old-todo.txt    website-copy/

Line by line, the four mv commands:

  1. rename todo-backup.txt to old-todo.txt (same folder, new name);
  2. move old-todo.txt into the existing folder archive;
  3. move and rename notes.txt in one step: it ends up in archive/2026/october as october-notes.txt;
  4. move a whole folder, website-copy, into archive.

The rule for both cp and mv: if the last argument is an existing folder, the item goes inside it and keeps its name; otherwise the last argument is the new name.

17.6 Deleting: rmdir and rm

17.6.1 rmdir: remove an empty folder

rmdir reports

This works because reports is empty. rmdir refuses to delete a folder that contains anything - a built-in safety check:

$ rmdir archive
rmdir: archive: Directory not empty

(Git Bash: rmdir: failed to remove 'archive': Directory not empty.)

17.6.2 rm: remove files

rm ideas.txt

rm (remove) deletes files immediately. Add -i to be asked first:

$ rm -i todo.txt
remove todo.txt? y

Type y and press Enter to delete, or n to keep the file. (Git Bash asks rm: remove regular empty file 'todo.txt'?.)

17.6.3 rm -r: remove a folder and everything in it

On its own, rm refuses to delete a folder:

$ rm archive
rm: archive: is a directory

(Git Bash: rm: cannot remove 'archive': Is a directory.) With -r, it deletes the folder and every file and folder inside it, all the way down:

rm -r archive
ls

This time ls prints nothing: the playground is empty.

rm is forever
  • There is no Trash or Recycle Bin. Files deleted with rm do not go to the Mac Trash or the Windows Recycle Bin. There is no undo.
  • -f means “force”: never ask, and stay quiet about missing files. You will often see rm -rf in instructions and AI answers. It deletes a folder and everything in it without a single question, so use it only when you are sure.
  • One typo can be a disaster. rm -rf ~ /old-stuff (do not type this) has a stray space after ~, so it means “delete my entire home folder, and also /old-stuff”. Never run an rm -rf you don’t fully understand - whether it comes from a website, a classmate, or an AI.
  • Habits that help: run pwd and ls first; use rm -i when in doubt; name exactly the files you mean; and keep your projects in Git (see What Is Version Control?), so that committed work can be recovered.

17.6.4 When an AI agent deletes files

As of Oct 6, 2026 · Official docs: Checkpointing · Choose a permission mode

Claude Code can run rm, mv, and cp too. Depending on its permission mode, it asks you first, lets an automatic safety check review the command, or - in the mode that auto-accepts edits - runs commands such as rm and mv inside your project without asking. Its checkpoints let you rewind changes it made with its own file-editing tools, but its documentation states that they do not undo file changes made by shell commands like these. Permission modes and Claude Code’s other safeguards are covered in Permissions, Modes, and Safety.

17.7 Names with spaces need quotes

Back in the (now empty) playground, try to create a folder called new folder:

$ mkdir new folder
$ ls -F
folder/ new/
$ mkdir new folder
$ ls -F
folder/  new/

Bash splits a command line at spaces, so mkdir received two names and created two folders. Remove them both and try again with quotes:

$ rmdir new folder
$ mkdir "new folder"
$ ls -F
new folder/

The quotes turn new folder into a single argument. You need them every time you use that name: cd "new folder", rmdir "new folder". (Git Bash displays the name as 'new folder'/; the quotes in the listing just show that it is one name.) Tab completion helps: it types a backslash before the space for you (new\ folder/), which works too. Quotes are explained fully in Writing to Files and Single Quotes vs. Double Quotes. The simplest fix is to avoid spaces in names you create.

Finally, clean up. The last rmdir works because the playground is empty again:

rmdir "new folder"
cd ..
rmdir playground

17.8 Command summary

Command What it does
mkdir name Create a folder.
mkdir -p a/b/c Create nested folders; no error if they already exist.
touch file Create an empty file (or update its “last modified” time).
cp file new-name / cp file folder Copy a file to a new name / into a folder.
cp -r folder new-folder Copy a folder and everything in it.
mv old-name new-name Rename a file or folder.
mv item folder Move a file or folder into a folder.
rmdir folder Delete an empty folder.
rm file Delete a file - permanently.
rm -r folder Delete a folder and everything in it - permanently.
-i (with cp, mv, rm) Ask before overwriting or deleting.

Practice Questions

Unless a question says otherwise, Maria is in /Users/maria/Documents/bash-tutorial-files (the practice files; see the tree on Files, Folders, and Paths).

Easy

Question 1 · Multiple choice

Which command creates a new, empty folder named invoices?

  1. touch invoices
  2. mkdir invoices
  3. cp invoices
  4. mv invoices

b. mkdir makes a directory. touch invoices would create an empty file named invoices. cp and mv need a source and a destination; they copy or move something that already exists.

Question 2 · Short answer

What does touch report.txt do if report.txt does not exist? And if it already exists?

If it doesn’t exist, touch creates it as an empty file. If it already exists, touch leaves the contents alone and only updates the file’s “last modified” time.

Question 3 · True or false

Files you delete with rm go to the Trash (Mac) or Recycle Bin (Windows), so you can get them back.

False. rm deletes immediately and permanently; there is no Trash and no undo. Only a backup or a Git commit can bring the file back.

Question 4 · Matching

Match each command with its effect.

Command Effect
1. mkdir -p a/b/c A. delete a folder and everything inside it
2. cp -r site site-backup B. delete an empty folder
3. rm -r site C. create nested folders in one step
4. rmdir site D. ask before deleting a file
5. rm -i notes.txt E. copy a folder and everything inside it

1 → C, 2 → E, 3 → A, 4 → B, 5 → D.

Question 5 · Multiple choice

Which command do you use to rename a file?

  1. rn
  2. cp
  3. mv
  4. rename-file

c. mv old-name new-name renames: moving and renaming are the same operation. cp would leave the original in place and create a second file. rn and rename-file are not standard Bash commands.

Question 6 · Short answer

What does the -r option stand for, and with which two commands on this page do you need it for folders?

-r means recursive: “the folder and everything inside it, all the way down”. You need it with cp (to copy a folder) and with rm (to delete a folder). mv moves folders without it.

Medium

Question 7 · Write the command

Write one command that creates the folders mobile-app and mobile-app/src inside projects (neither exists yet).

mkdir -p projects/mobile-app/src

-p creates any missing parent folders. Without it, mkdir would fail with “No such file or directory” because projects/mobile-app doesn’t exist yet.

Question 8 · Write the command

Maria is in projects/data-analysis. Write the command that renames data.csv to sales-2026.csv.

mv data.csv sales-2026.csv

Question 9 · Write the command

Write one command that copies pictures/family.jpg into the documents folder, keeping its name.

cp pictures/family.jpg documents

Because documents is an existing folder, the copy goes inside it as documents/family.jpg. (cp pictures/family.jpg documents/family.jpg is also correct.)

Question 10 · Write the command

Before experimenting, Maria wants a complete backup of the projects folder, called projects-backup. Write the command.

cp -r projects projects-backup

-r is required because projects is a folder; without it, cp refuses to copy it.

Question 11 · Predict the output

In an empty folder, Maria runs:

mkdir quarterly reports
ls

What does ls show, and why? How should she have typed the command to get one folder named quarterly reports?

ls shows two folders, quarterly and reports. Bash splits the command line at spaces, so mkdir received two names. To create one folder, quote the name:

mkdir "quarterly reports"

(mkdir quarterly\ reports also works.)

Question 12 · Predict the output

Maria runs rmdir documents. What happens, and why?

It fails with an error ending in Directory not empty (Mac: rmdir: documents: Directory not empty). rmdir only deletes empty folders, and documents contains notes and reports. Nothing is deleted.

Question 13 · Fill in the blank

rm music fails with the message “______” because music is a folder. To delete it together with its contents you would type rm ______ music.

“is a directory” (Mac: rm: music: is a directory; Git Bash: rm: cannot remove 'music': Is a directory), and rm -r music.

Question 14 · Compare

What is the difference between cp notes.txt archive and mv notes.txt archive (where archive is an existing folder)?

Both put a file called notes.txt inside archive. After cp, the original notes.txt is still in the current folder (you have two copies). After mv, the original is gone from the current folder (there is only one file, now inside archive).

Hard

Question 15 · Scenario

Maria’s todo.txt contains her to-do list. She meant to make a backup but typed:

cp notes.txt todo.txt

What happened to her to-do list? How could she have protected herself?

cp copied notes.txt over todo.txt without asking, so todo.txt now contains the notes, and the to-do list is lost (there is no undo). She could have:

  • used cp -i, which asks before overwriting;
  • double-checked the order: cp source destination (she wanted cp todo.txt todo-backup.txt);
  • kept the folder in Git, so the last committed version could be restored.

Question 16 · Find the bug

Sam wants to delete an empty folder named old reports and types:

rmdir old reports

What does Bash actually try to do? Describe a case where this could delete the wrong thing, and write the correct command.

Bash splits at the space, so rmdir tries to delete two folders, old and reports. If they don’t exist, Sam just gets two errors. But if an empty folder called reports happens to exist in the current folder, it gets deleted by mistake - and old reports is still there. The correct command:

rmdir "old reports"

Question 17 · Scenario

An AI chatbot tells you to “clean up” by running:

rm -rf old-site

Explain each part of the command. What would you check before running it?

  • rm: remove (delete), permanently.
  • -r: recursive - the folder and everything inside it.
  • -f: force - never ask for confirmation and don’t complain about missing files.
  • old-site: the folder to delete, as a relative path.

Before running it: check where you are (pwd) and what old-site contains (ls old-site); make sure nothing in it is needed (or that it is backed up or committed to Git); and be sure the name is spelled exactly right. Dropping -f (or using rm -ri) gives you a chance to confirm.

Question 18 · Short answer

Explain why rm -rf ~ /old-stuff is so dangerous, even though the person who typed it only wanted to delete ~/old-stuff.

The stray space splits the path into two arguments: ~ (the whole home folder) and /old-stuff. With -r and -f, rm would delete the entire home folder - documents, photos, projects - without asking. The intended command was rm -rf ~/old-stuff (no space). This is why you should read every rm -rf character by character before pressing Enter.

Question 19 · Ordering

Maria wants to keep a backup of documents/notes/ideas.txt in a new folder backup, then rename the original to ideas-v1.txt, and finally check the result. Put these commands in a working order:

  • ls backup documents/notes
  • mv documents/notes/ideas.txt documents/notes/ideas-v1.txt
  • mkdir backup
  • cp documents/notes/ideas.txt backup
mkdir backup
cp documents/notes/ideas.txt backup
mv documents/notes/ideas.txt documents/notes/ideas-v1.txt
ls backup documents/notes

The folder must exist before you copy into it, and the copy must happen before the rename (afterwards, ideas.txt no longer exists under that name).

Question 20 · Compare

Both rmdir photos and rm -r photos can delete a folder. When is rmdir the safer choice?

rmdir only deletes empty folders and refuses otherwise, so it can never destroy files by accident. Use it when you believe a folder is empty: if you are wrong, you get an error instead of losing files. rm -r deletes the folder and everything inside it, so use it only after checking the contents.

Question 21 · Scenario

During a Claude Code session, Claude ran the shell command rm draft.txt. Later you realize you needed that file. Can Claude Code’s checkpoints (its rewind feature) bring it back? What could?

According to the Claude Code documentation, no: checkpoints track changes made with Claude’s own file-editing tools, not files changed by shell commands such as rm, mv, or cp. The file could only come back from somewhere else - for example, a Git commit that contains it (or another backup). This is one reason to commit your work before letting an agent make big changes.

© 2025-2026 Y. Rosenthal. All rights reserved.