4.1 Create, Delete, Copy, and Move Files and Directories
Key Takeaways
- mkdir -p creates parent path components as needed; rmdir removes only empty directories while rm -r removes trees recursively.
- cp copies; use cp -a (or -dR --preserve=all) when you must keep permissions, ownership, timestamps, and links for admin backups.
- mv renames or relocates files and directories on the same or different filesystems; it does not leave a second copy behind.
- rm removes directory entries; rm -r (and carefully rm -rf) deletes directory trees—always confirm paths with pwd and ls before destructive flags.
- Touch creates empty files or updates timestamps; combine mkdir -p, cp -a, mv, and rm into deliberate workflows so exam artifacts end in the correct path with correct attributes.
4.1 Create, Delete, Copy, and Move Files and Directories
Quick Answer: Create directories with
mkdir/mkdir -p, empty files withtouch, copy withcp(usecp -ato preserve attributes), move or rename withmv, and remove withrm/rm -r. Always verify identity, path, and attributes withpwd,ls -l, andstatbefore and after changes.
The EX200 essential-tools objective to create, delete, copy, and move files and directories is pure day-to-day Linux administration. Almost every later task—deploying configs under /etc, staging content under /var, or assembling a home-directory lab—depends on getting paths, recursion, and attributes right the first time.
Mental Model: Directory Entries and Trees
A file is data identified by an inode (metadata: size, permissions, timestamps, ownership). A directory is a special file that maps names to inodes. When you cp, mv, or rm, you manipulate names and sometimes data:
| Action | Typical effect |
|---|---|
touch name | Create empty file or update timestamps |
mkdir name | Create a directory entry |
cp src dest | New name and usually new inode/data copy |
mv src dest | Change name/location (same inode if same filesystem) |
rm name | Remove directory entry; data freed when last link is gone |
Hard and soft links (next section) build on this inode model. For this section, treat every exam path as something you must create correctly, place correctly, and not destroy accidentally.
Creating Directories: mkdir
mkdir project
mkdir -p /home/student/labs/ex200/files
mkdir -m 755 /srv/www
mkdir dir1 dir2 dir3
| Option | Purpose |
|---|---|
-p | Create parent directories as needed; no error if the path already exists |
-m mode | Set mode at creation (subject to umask interaction—verify with ls -ld) |
| multiple names | Create several directories in one command |
Why -p matters on the exam: Tasks often specify deep paths (/home/bob/projects/app/config). Without -p, mkdir fails if a parent is missing. With -p, one command builds the whole chain. mkdir -p is also safe when re-running a recipe: existing directories are left alone rather than failing.
Verify:
ls -ld /home/student/labs/ex200/files
namei -l /home/student/labs/ex200/files # optional path walk
Creating Empty Files and Updating Timestamps: touch
touch notes.txt
touch /tmp/a /tmp/b /tmp/c
touch -t 202608051200.00 stamped.txt # set explicit timestamp when required
touch creates a zero-length file if the name does not exist, or updates access/modification times if it does. Exam tasks often say “create an empty file named X in directory Y”—touch Y/X after mkdir -p Y is the standard pattern.
Other quick creation methods (already familiar from editing/redirection chapters):
echo 'content' > file.txt
cat > file.txt <<'EOF'
line1
line2
EOF
Prefer touch when content is not required yet; prefer redirection or an editor when the file must contain specific text.
Copying: cp
cp source dest
cp file1 file2 file3 /path/to/dir/
cp -r sourcedir destdir
cp -a sourcedir destdir
Essential options
| Option | Purpose |
|---|---|
-r or -R | Recursive copy of directories |
-a | Archive mode: recursive + preserve attributes (roughly -dR --preserve=all) |
-p | Preserve mode, ownership (if permitted), and timestamps |
-v | Verbose—show what is copied |
-i | Interactive prompt before overwrite |
-n | No clobber (do not overwrite) |
-d | Preserve symlinks as symlinks (do not follow) |
-L | Always follow symlinks (copy the target content) |
When to use cp -a
Exam trap: A plain cp -r copies content but may not fully preserve ownership, permissions, timestamps, or special file types the way an administrator backup should. Graders (and real restore drills) often care about:
- Permission bits and ownership
- Timestamps
- Symlinks remaining symlinks
- Extended attributes where relevant
Prefer cp -a when the task says “preserve attributes,” “exact copy,” “backup,” or when copying system trees you will compare with ls -l / stat later.
cp -a /etc/ssh /root/ssh-backup
ls -l /etc/ssh/sshd_config /root/ssh-backup/sshd_config
stat /etc/ssh/sshd_config /root/ssh-backup/sshd_config
If you copy as an unprivileged user into a path you own, ownership of new files is typically your UID—even when the source was root-owned. Only root (or capable processes) can create root-owned copies. Use sudo cp -a when the destination must keep original ownership under restricted paths.
Destination rules
- If dest is an existing directory, sources are placed inside it with the same basenames.
- If dest does not exist and you copy one file, dest becomes the new file name.
- If dest does not exist and you use
cp -r srcdir destdir, destdir is created as the copy of srcdir.
cp report.txt /tmp/ # /tmp/report.txt
cp report.txt /tmp/report.bak # renamed copy
cp -a project /tmp/ # /tmp/project/...
Moving and Renaming: mv
mv oldname newname
mv file1 file2 dir3 /path/to/dir/
mv project /home/student/archive/
mv renames when source and destination are on the same filesystem (inode stays the same; only the directory entry changes). Across filesystems, mv typically copies then removes the original—behavior you notice if a huge tree move is slow or if attributes fail to transfer under restricted permissions.
| Situation | Result |
|---|---|
mv a b and b does not exist | Rename a → b |
mv a b and b is a directory | Move a into b/ |
mv a b and b is an existing file | Overwrite b (prompt if -i or alias forces it) |
Useful options: -i (interactive), -n (no clobber), -v (verbose).
Exam use cases: Rename files to match a required name, relocate a completed project into a grading path, or reorganize after creating content in the wrong directory. Unlike cp, successful mv does not leave the original path behind—do not use mv when you still need the source in place.
Removing: rm and rmdir
rmdir — empty directories only
rmdir emptydir
rmdir -p a/b/c # remove c, then b, then a if each becomes empty
If the directory is not empty, rmdir fails. That is a safety feature, not a bug.
rm — files and trees
rm file.txt
rm -r directory/
rm -rf directory/ # recursive + force (no prompts; dangerous)
rm -i file1 file2 # prompt each
| Option | Purpose |
|---|---|
-r / -R | Recursive delete of directories |
-f | Force; ignore nonexistent files and usually skip prompts |
-i | Prompt before each removal |
-d | Remove empty directories (like rmdir) on some implementations |
Exam discipline:
pwdandlsbeforerm -r.- Prefer absolute paths for destructive commands on system trees.
- Avoid casual
rm -rf /patterns and watch trailing spaces/globs (rm -rf $VAR/whenVARis empty is catastrophic in scripts). - Remember that
rmremoves names; if other hard links exist, data may remain under another name (next section).
Aliases on some interactive shells map rm to rm -i. On exams, know the real binary behavior and do not assume prompts will always save you—especially in scripts or bash -c.
Building a Complete Workflow
Typical multi-step task wording: “Create directory structure X; place files; copy a template preserving permissions; move the tree to Y; remove temporary files.”
whoami
mkdir -p /home/student/work/app/{bin,etc,data}
touch /home/student/work/app/etc/app.conf
echo 'listen=8080' > /home/student/work/app/etc/app.conf
cp -a /usr/share/doc /home/student/work/app/data/doc-backup 2>/dev/null || true
mv /home/student/work/app /home/student/final-app
rm -r /home/student/work
ls -laR /home/student/final-app
Brace expansion {bin,etc,data} creates multiple siblings under one parent—fast and accurate under time pressure. Confirm with ls -laR or targeted find.
Preserving Attributes and Comparing Results
After copies that must match the source:
ls -l source dest
stat source dest
getfacl source dest # if ACLs are in play later
Timestamps, mode bits, and ownership are the first things graders or automated checks compare. If you used plain cp and the task implied an archival copy, fix with a fresh cp -a rather than manually chasing every bit.
Common Pitfalls
- Forgetting
-r/-aon directories —cp dir destwithout recursion fails or does not copy the tree as intended. - Using
cpwhen the task wants a rename — leaves duplicates and wrong paths. - Using
mvwhen you still need the original — source disappears. rm -ron the wrong path — no recycle bin on the exam.- Creating as root under a user home — ownership ends up root:root; fix with
chownor recreate as the correct user. - Assuming
cp -requalscp -a— attribute and symlink handling differ; prefer-afor admin-quality trees. - Relative path mistakes — always
pwdwhen staging multi-step file trees.
RHEL Practice Drill
mkdir -p /tmp/sg-files/{src,dst}
echo alpha > /tmp/sg-files/src/a.txt
cp -a /tmp/sg-files/src/a.txt /tmp/sg-files/dst/a-copy.txt
mv /tmp/sg-files/dst/a-copy.txt /tmp/sg-files/dst/a-renamed.txt
cp -a /tmp/sg-files/src /tmp/sg-files/dst/src-backup
rm /tmp/sg-files/src/a.txt
rmdir /tmp/sg-files/src || rm -r /tmp/sg-files/src
ls -laR /tmp/sg-files
Explain to yourself after each step what still exists and what attributes ls -l shows.
Section Checkpoint
You should be able to build nested directories with mkdir -p, create files with touch or redirection, copy single files and whole trees with correct recursion, use cp -a when attributes must survive, relocate or rename with mv, and remove files or empty/non-empty directories with rmdir / rm -r without collateral damage. Those operations are the foundation for links and archives in the next sections.
You must create the full path /home/student/projects/app/config in one command even if intermediate directories do not exist yet. Which command is correct?
An exam task says to copy a directory tree so that permissions, ownership (as permitted), timestamps, and symbolic links are preserved as closely as possible. Which cp form is the best default on RHEL?
What is the primary difference between mv report.txt archive/report.txt and cp report.txt archive/report.txt when both succeed on the same filesystem?
Which command removes a non-empty directory tree named /tmp/oldlab including all nested files?