Create your own
Lesson illustration

Safely Managing Files and Directories from the Shell

Hello again. Last time, you learned to orient yourself in the filesystem with pwd, ls, and cd, and to distinguish absolute paths from relative ones. That orientation is the first safety measure in shell work: before changing anything, know where you are.

This lesson turns navigation into controlled file management. You will create a small AI-infrastructure-style workspace, copy and rename artifacts, move files into directories, and remove only deliberately chosen test data. These are everyday operations when organizing configuration files, request samples, logs, checkpoints, and model artifacts.


The basic model: an action, a source, and a destination

Most file-management commands follow a consistent pattern:

command [options] source destination

For example:

cp notes.txt notes-backup.txt

means: copy the source file notes.txt and create a destination file named notes-backup.txt.

The core commands are:

GoalCommandExample
Create a directorymkdirmkdir logs
Create an empty filetouchtouch requests.json
Copycpcp config.yaml config-backup.yaml
Move or renamemvmv old-name.txt new-name.txt
Remove a filermrm temporary.txt
Remove an empty directoryrmdirrmdir empty-dir
Remove a directory and its contentsrm -rrm -r old-run

The destination is important because it can mean two different things:

cp report.txt archive
  • If archive is an existing directory, this creates archive/report.txt.
  • If archive does not exist, this creates a new file named archive containing a copy of report.txt.

When you intend a destination to be a directory, a trailing slash can make that intent clearer:

cp report.txt archive/

If archive is not actually a directory, this command fails rather than silently creating an unexpected file.

The short video below provides a visual demonstration of the commands you will use. It treats folders as directories—the two words mean the same thing in this context.

Linux/Mac Terminal Tutorial: Create, Copy, Move, Rename and Delete Files and Directories

Watch “Linux/Mac Terminal Tutorial: Create, Copy, Move, Rename and Delete Files and Directories” by Corey Schafer for a compact visual walkthrough of file operations.

Watch creating entries to see mkdir and touch. Then watch file operations for copying, renaming, moving, and the permanence of rm. Finish with directory operations, focusing on why copying and deleting directories needs recursive options.


Create a safe workspace first

Do not practice destructive commands in your home directory at random, and never practice them in locations such as /etc, /var, or /usr. Instead, create one clearly named sandbox under your home directory.

Run these commands exactly:

mkdir -p ~/ai-infra-lab/file-ops/incoming
mkdir -p ~/ai-infra-lab/file-ops/archive
cd ~/ai-infra-lab/file-ops
pwd
ls

Your final pwd should end in:

/ai-infra-lab/file-ops

The full beginning will vary because it includes your own home directory path.

Creating directories with mkdir

mkdir means “make directory”:

mkdir logs

This creates a logs directory inside your current directory.

You can create more than one directory in one command:

mkdir raw-data processed-data

For a nested path, use mkdir -p:

mkdir -p checkpoints/run-01

The -p option means “create parent directories as needed.” If checkpoints does not exist yet, Linux creates it before creating run-01. It also avoids an error if the directories already exist, which is useful in repeatable setup commands.

Create a nested directory in your sandbox:

mkdir -p checkpoints/run-01

Creating empty files with touch

A file does not need to contain data to exist. The touch command creates an empty file when the name does not already exist:

touch requests-001.json

Create a few deliberately harmless placeholder artifacts:

touch requests-001.json requests-002.json notes.txt
touch checkpoints/run-01/metadata.json
ls

These are only empty files, but their names resemble assets you might encounter in an infrastructure project:

  • JSON request examples sent to an inference API;
  • notes about a test run;
  • metadata stored alongside a model checkpoint.

One caveat: if a file already exists, touch normally updates its modification timestamp rather than creating a new file. It is therefore useful for creating placeholders, but should not be casually run on important files when timestamps matter.

Name files for the shell, not just for humans

Linux filenames are case-sensitive: Model.bin and model.bin are different files. A practical naming convention is:

lower-case-with-hyphens

For example:

model-config.yaml
request-sample-01.json
checkpoint-run-01

Spaces are valid in names, but they require quoting or escaping at the shell:

mkdir "model outputs"

Prefer model-outputs or model_outputs instead. Simple names reduce mistakes in scripts, containers, and deployment configurations.


Copying preserves the source; moving does not

The difference between cp and mv is fundamental:

  • cp creates another copy; the source remains.
  • mv relocates or renames the original; the old source path no longer exists.

Copy a file

Copy one request sample into the incoming directory:

cp -i requests-001.json incoming/
ls incoming

The -i means interactive. If a destination file with the same name already exists, Linux asks before overwriting it. Use -i while learning and whenever overwriting would be costly.

Now make a backup with a different filename in the current directory:

cp -i notes.txt notes-backup.txt
ls

You should now have both notes.txt and notes-backup.txt.

Without -i, the following command can silently replace notes-backup.txt if it already exists:

cp notes.txt notes-backup.txt

That is why copying is not automatically “safe” merely because the original remains intact: the destination may still be overwritten.

Copy a directory recursively

Directories can contain other directories and files. To copy the complete tree, use recursive copying:

cp -R incoming incoming-copy
ls incoming-copy

-R means recursive: copy the directory and everything beneath it. On many Linux systems, -r also works, but -R clearly conveys the intent to recurse through a directory tree.

Be attentive to whether the destination directory already exists:

cp -R incoming archive/

Because archive/ already exists, this produces:

archive/incoming/

rather than replacing archive itself.

Rename with mv

Linux has no separate general-purpose rename command for this basic task. Renaming is treated as moving a path to a new name:

mv -i notes-backup.txt notes-copy.txt

Afterward, notes-backup.txt is gone and notes-copy.txt exists.

Move and rename the file in one operation:

mv -i notes-copy.txt archive/notes-archived.txt
ls archive

The source is now gone from the current directory. Its new location is:

archive/notes-archived.txt

Move the remaining request sample without renaming it:

mv -i requests-002.json incoming/
ls incoming

Move a directory

mv works on directories without a recursive option:

mv -i incoming-copy archive/
ls archive

Since archive/ already exists, the result is a nested directory:

archive/incoming-copy/

This is a common source of surprises. Compare these two commands:

mv run-01 run-02

If run-02 does not exist, this renames run-01 to run-02.

mv run-01 experiments/

If experiments/ exists, this moves the directory to:

experiments/run-01/

Before moving a directory, inspect the destination with ls and decide whether you expect a rename or a nested move.


Wildcards are powerful because the shell expands them first

A wildcard is a pattern that the shell expands into one or more filenames before it runs your command.

The two most useful patterns are:

PatternMeaningExample
*Zero or more charactersrequest-*.json
?Exactly one characterrequest-???.json

Suppose the current directory contains:

request-001.json
request-002.json
request-010.json
notes.txt

Then:

ls request-???.json

matches the three request files because each has exactly three characters between the hyphen and .json.

And:

ls request-*.json

matches any filename beginning with request- and ending in .json, regardless of how many characters are in the middle.

Wildcards are efficient for bulk work, but they are also risky with destructive commands. First inspect what a pattern matches using ls; only then reuse that tested pattern with cp, mv, or rm.

Learning the shell - Lesson 5: Manipulating Files

Read this concise LinuxCommand.org guide to reinforce the command patterns and, especially, the safety rule for using wildcards with deletion.

In the “Wildcards” section, read the wildcard explanation and compare * with ?. Then read the example tables in the “cp” and “mv” sections. In “mv,” read the move versus rename distinction. Finally, under “Be careful with rm!”, read the deletion warning, then finish that warning paragraph and review the “Command examples using wildcards” table.


Removing files and directories safely

Deletion is the operation where careful habits matter most. In a typical terminal workflow, rm does not send files to a graphical trash folder. Removal is intended to be permanent.

Remove an individual file

First remove notes.txt, which is still in your current directory:

rm -i notes.txt

Confirm only if the prompt names notes.txt.

Afterward, verify:

ls

The -i option is a useful guardrail. It does not make a mistaken command harmless, but it gives you a chance to stop before removal.

Remove an empty directory with rmdir

rmdir removes directories only when they are empty. Create and remove a test directory:

mkdir empty-dir
rmdir empty-dir

This is a deliberately conservative command. If a directory contains files, rmdir refuses to remove it.

Remove a non-empty directory with rm -r

To remove a directory tree, rm needs the recursive option:

mkdir -p throwaway/nested
touch throwaway/nested/temporary.txt
ls throwaway
rm -r -i throwaway

Read every prompt before responding. You should only confirm entries under the exact throwaway directory you just created.

rm -r can delete a large nested tree quickly. Avoid rm -rf while learning:

  • -r means recursively descend into directories.
  • -f means force: suppress many warnings and prompts.

Together, they remove important safety checks. For normal work, prefer a narrowly specified path and add -i when deleting manually.

Test wildcards before removal

Now create disposable files:

touch scratch-01.tmp scratch-02.tmp keep.txt
ls

Preview the wildcard match:

ls scratch-*.tmp

You should see only:

scratch-01.tmp
scratch-02.tmp

Only after confirming that output, run:

rm -i scratch-*.tmp

Do not replace the pattern with *. That would match almost everything in the current directory, including directories and files you intend to keep.

A reliable removal routine is:

  1. Run pwd to confirm your current directory.
  2. Run ls to inspect the relevant files.
  3. Use an explicit path where possible.
  4. Test any wildcard with ls first.
  5. Use rm -i for manual deletion.
  6. Avoid recursive deletion unless you have confirmed the directory and its contents.

For a future project, you could preserve this ~/ai-infra-lab directory as a safe location for shell experiments. Do not remove it with a broad command from your home directory.


Key takeaways

  • mkdir creates directories; mkdir -p can create nested directories and required parents.
  • touch creates empty files when they do not already exist.
  • cp copies and preserves the source; use cp -i to avoid accidental overwrites.
  • cp -R copies a directory tree.
  • mv both moves and renames. Its result depends on whether the destination already exists as a directory.
  • rm removes files; rmdir removes only empty directories; rm -r removes directory trees and requires special care.
  • Wildcards such as * and ? select groups of filenames. Preview them with ls before using them in any destructive command.
  • Keep experiments inside a purpose-built sandbox under your home directory.

Next, you will learn to make command output useful: redirect output to files, combine commands with pipes, and search logs using tools such as grep, sort, and tail.

Can't find a good explanation? Sign up and we'll make it for you

Sign up