Basic File Management - cp, mv, rm, touch, and Wildcards
What You Will Achieve
- Use the main options of
cp/mv/rm(-r-a-i-p-u-f) appropriately - Create empty files and update timestamps with
touch - Create and delete directories safely with
mkdir -p/rmdir - Write wildcards (
*?[ ][!...]) and brace expansion ({ }) correctly - Explain that it is the shell, not the command, that expands globs
This is the core of LPIC-1 objective 103.3 "Perform basic file management". Master the patterns to do the file operations that make up most of daily work without accidents.
Which Command and Option to Choose
Choose file operations by "what you want to do" and "how to prevent accidents". The table below is the starting point.
| What you want | Command | Safety habit |
|---|---|---|
| Copy | cp |
-i (overwrite prompt) |
| Backup (keep attrs) | cp -a |
-a = recursive + preserve |
| Move / rename | mv |
-i (overwrite prompt) |
| Delete | rm |
-i (confirm each) |
| Create / update file | touch |
Keeps existing content intact |
| Create directory | mkdir -p |
Create parents at once |
| Remove empty directory | rmdir |
Fails if not empty (safe) |
When in doubt, make "add -i to destructive operations (rm / overwriting mv)" your default stance. The fact that rmdir fails unless empty is not a flaw but a safety valve against accidental deletion.
Using cp / mv / rm
cp - Copy and Option Differences
cp duplicates files and directories. Directories require -r (recursive). For backups, use -a, which also preserves attributes.
cp file1.txt file2.txt cp -r src/ backup/ cp -a src/ archive/
$ ls -l file2.txt -rw-r--r-- 1 user user 0 May 30 10:00 file2.txt
The main options mean the following. This assumes GNU coreutils cp.
| Option | Meaning |
|---|---|
-r, -R |
Copy directories recursively |
-a |
Archive mode. Equivalent to -dR --preserve=all (keep attrs) |
-i |
Prompt before overwriting |
-p |
Preserve attributes such as mtime, owner, and permissions |
-u |
Copy only when the destination is older or missing (update) |
-r means "copy the contents", while -a means "copy the contents plus fully preserve attributes, symbolic links, and timestamps". Remember -r for a simple duplicate and -a for a backup.
-u (update) is handy for differential sync. cp -au src/ dst/ copies "only newer files while preserving attributes", usable as a simple backup.
mv - Move and Rename
mv serves both move and rename. mv old new in the same directory is a rename, and mv file dir/ to another directory is a move. Add -i where overwriting is risky.
mv draft.txt report.txt mv report.txt /home/user/docs/ mv -i report.txt /home/user/docs/
$ mv -i report.txt /home/user/docs/ mv: overwrite '/home/user/docs/report.txt'? n
| Option | Meaning |
|---|---|
-i |
Prompt before overwriting |
-f |
Force overwrite without prompting (cancels -i) |
Unlike cp, mv does not need -r to move a directory. Within the same filesystem it only rewrites the path information without moving the data itself, so it is fast.
rm - Delete and the Danger of -rf
rm deletes files. Use -r to delete directories and -f to force deletion without prompting. There is no "trash" with rm; deletion means immediate removal.
rm unwanted.txt rm -i unwanted.txt rm -r olddir/
$ rm -i unwanted.txt rm: remove regular file 'unwanted.txt'? y
| Option | Meaning |
|---|---|
-r, -R |
Delete directories recursively |
-f |
Suppress existence checks and prompts; force delete |
-i |
Confirm each item before deleting |
rm -rf deletes a directory tree at once without confirmation. A typo in an argument (for example, a stray space after / as in rm -rf / tmp/foo) can destroy the entire system. Always visually confirm the target paths before running, and combine with -i if unsure.
touch / mkdir / rmdir / file
touch - Create Empty Files and Update Timestamps
touch creates a nonexistent file as empty, and for an existing file it updates the access and modification times to the current time (without changing the content).
touch newfile.txt touch existing.txt touch -c missing.txt
$ ls -l --time-style=+%H:%M newfile.txt -rw-r--r-- 1 user user 0 10:05 newfile.txt
| Option | Meaning |
|---|---|
-a |
Update access time only |
-m |
Update modification time only |
-c |
Do not create the file if it does not exist |
-t |
Set to the specified time ([[CC]YY]MMDDhhmm[.ss]) |
Running touch on an existing file does not erase data. It is also used to manipulate the modification time, such as forcing a rebuild (make's timestamp check).
mkdir / rmdir - Create and Delete Directories
mkdir creates a directory. For a deep hierarchy whose parents do not exist, use -p to create them all at once. rmdir deletes only an empty directory.
mkdir project mkdir -p project/src/lib rmdir project/src/lib
$ rmdir project rmdir: failed to remove 'project': Directory not empty
Without -p, you cannot create a directory under a nonexistent parent and get an error. That rmdir "fails unless empty" is a safety mechanism; to delete contents and all, use rm -r (which is correspondingly more dangerous).
file - Determine File Type from Content
file determines a file's type by examining its content, not its extension. It can see through a faked extension to the real entity.
file report.pdf script.sh archive.gz photo
report.pdf: PDF document, version 1.7 script.sh: Bourne-Again shell script, ASCII text executable archive.gz: gzip compressed data photo: JPEG image data, JFIF standard 1.01
Even photo with no extension is identified as JPEG. Checking the type with file before opening with cat and getting garbled output is a safe habit.
Wildcards and Shell Expansion
Wildcards (globs) are a mechanism to specify file-name patterns in bulk. The key point is that it is the shell, not cp or rm, that expands them. The shell replaces the pattern with actual file names before passing them to the command.
| Pattern | Matches | Example |
|---|---|---|
* |
Any string of zero or more characters | *.txt -> all .txt |
? |
Any single character | file?.txt -> file1.txt, fileA.txt |
[abc] |
Any one of the characters in brackets | file[12].txt -> file1.txt, file2.txt |
[a-z] |
Any one character in the range | [a-c]* -> names starting a/b/c |
[!abc] |
Any single character not in brackets | file[!0].txt -> not file0.txt |
Brace expansion { } is different from globs: it mechanically generates strings regardless of whether files exist.
echo file{A,B,C}.txt
echo {1..3}.log
mkdir -p project/{src,test,docs}fileA.txt fileB.txt fileC.txt 1.log 2.log 3.log
{A,B,C} is a comma-separated list and {1..3} is a numeric sequence. mkdir -p project/{src,test,docs} creates three directories in one shot.
Brace expansion creates strings even if no files exist (generative). Globs * ? [ ], on the other hand, match existing file names (search). *.txt matches nothing if there is no .txt, and in default bash the pattern string itself is passed to the command. Keep this in mind.
ls *.nonexistent echo *.nonexistent
ls: cannot access '*.nonexistent': No such file or directory *.nonexistent
When a glob matches nothing, bash by default passes the pattern as is (echo prints that string, and ls says "no such file"). You can change this to "expand to empty when there are zero matches" by setting shopt -s nullglob.
Common Mistakes and Fixes
Here are the points that trip people up in both practice and the exam.
- Forgetting
-rfor a directory incp:cp dir/ dst/gives anomitting directoryerror. Always use-ror-afor directory copies. - Confusing
-rand-a: Use-rfor a simple duplicate, and-afor a backup that preserves owner, permissions, links, and times. With-ralone the attributes change. - Overwriting silently with
mv: By defaultmvsilently overwrites an existing file. Make-ia habit for important files. - Running
rm *in root or an important directory: It is the shell that expands the glob. Prefixing withechoas inecho rm *to confirm what it expands to is safe. - Confused by the "not empty" error from
rmdir: This is the safe behavior as designed. To delete contents and all, userm -r, but always confirm the target.
Troubleshooting
Symptom: cp says "omitting directory" and copies nothing
Cause: Trying to copy a directory without -r (or -a)
Check:
file src
Fix: Use cp -r src/ dst/ for a directory, or cp -a src/ dst/ to also keep attributes.
Symptom: Files disappeared after running rm -rf
Cause: rm -rf deletes recursively without confirmation. rm has no undo
Check:
echo rm -rf target/
Fix: Prefix with echo to visually inspect the expansion before running. Combine with -i (rm -ri) if unsure. Deleted files can only be recovered from a backup.
Symptom: A wildcard does not match / the pattern is printed verbatim
Cause: Zero files match. bash by default passes the pattern string as is
Check:
shopt nullglob ls -d *.txt
Fix: Recheck the target directory and extension. To make it expand to empty on zero matches, set shopt -s nullglob.
Completion Checklist
- [ ] Explained and used the difference between
cp -randcp -a - [ ] Enabled overwrite/delete confirmation with
mv -i/rm -i - [ ] Confirmed empty-file creation and timestamp update with
touch - [ ] Confirmed the difference between
mkdir -pandrmdir - [ ] Wrote
*?[ ]and brace expansion{ }distinctly - [ ] Understood that it is the shell that expands globs
Summary
| Scenario | Command | Point |
|---|---|---|
| Copy | cp -r / cp -a |
-a preserves attributes too |
| Move / rename | mv -i |
Default overwrites silently |
| Delete | rm -ri |
No undo; -rf needs max caution |
| Create / update | touch / mkdir -p |
Keeps existing content intact |
| Remove empty dir | rmdir |
Fails if not empty (safe) |
| Determine type | file |
By content, not extension |
| Bulk specify | * ? [ ] { } |
The shell does the expansion |
Basic file management is the most frequently used area in LPIC-1. Once you solidify this, move on to the link mechanism that points to file entities, and to the FHS and finding files, to complete the picture.