Chapter 04Lesson 01~50 minutes

Creating, Copying, Moving, and Removing Files

File operations are among the most common and most destructive Linux tasks. This lesson develops a controlled workflow: identify exact paths, preview the operation, choose explicit command behavior, verify the result, and preserve a recovery path.

BeginnerFile operationsHands-on lab

Learning objectives

By the end of this lesson

  • Create directories and files with explicit, predictable paths.
  • Copy files and directory trees while choosing overwrite and metadata behavior deliberately.
  • Move and rename filesystem objects without losing track of source and destination semantics.
  • Remove files and directories with safeguards appropriate to interactive and automated work.
  • Apply preview, verification, and rollback habits to a realistic release-workspace lab.

1. A filesystem operation has a target and a consequence

Commands such as cp, mv, and rm look simple, but their effect depends on pathname resolution, whether a destination exists, shell expansion, permissions, filesystem boundaries, and command options. Reliable operators make those conditions visible before changing state.

Controlled file-operation workflow
flowchart TD
  I["Identify source and destination"] --> P["Print working directory and preview paths"]
  P --> C["Choose explicit command options"]
  C --> E["Execute one bounded operation"]
  E --> V["Verify names, type, size, and content"]
  V --> R["Retain backup or rollback path"]
Shell first, command second

Wildcards and variables may be expanded by the shell before cp, mv, or rm starts. Always reason about the final argument list, not merely the text you typed.

2. Create directories and files deliberately

mkdir creates directories. Without -p, it fails when a required parent is missing or when the target already exists. With -p, it creates missing parents and treats an existing directory as success.

workspace="$HOME/devops-academy/linux/chapter04/lesson01"
mkdir -p -- "$workspace"/{source,staging,archive}

# Create a file with known content rather than an ambiguous empty placeholder.
printf '%s\n' 'service_name=demo-api' 'port=8080' > "$workspace/source/app.conf"

# Create an empty marker only when emptiness is the intended state.
touch -- "$workspace/source/.initialized"

printf 'Created workspace:\n'
find "$workspace" -maxdepth 2 -printf '%y %p\n' | sort

The separator -- ends option parsing for commands that support it. A filename beginning with - is then treated as an operand rather than an option. Quoting variables preserves spaces and prevents unintended splitting and glob expansion.

CommandPurposeImportant behavior
mkdir dirCreate one directoryFails if the parent is absent or the target already exists
mkdir -p pathCreate a directory hierarchyUseful for idempotent setup, but still fails if a path component is a non-directory
touch fileCreate an empty file or update timestampsDoes not populate meaningful content
printf ... > fileCreate or replace a text fileTruncates an existing file before writing

3. Copy with explicit overwrite and metadata intent

cp SOURCE DESTINATION copies file data. When the destination names an existing directory, the source basename is placed inside that directory. When the destination is a non-directory pathname, it becomes the new name. This distinction is a common source of mistakes.

cd -- "$workspace"

# Copy one file to a new pathname. -v reports the operation.
cp -v -- source/app.conf staging/app.conf

# Refuse to overwrite an existing file.
cp -vn -- source/app.conf staging/app.conf

# Preserve mode, ownership when permitted, timestamps, and links for a tree.
cp -a -- source/. staging/source-snapshot/

# Compare copied content.
cmp -- source/app.conf staging/app.conf && printf 'content matches\n'
-n

No clobber

Do not overwrite an existing destination. Useful for cautious interactive copying, though scripts should still verify the result.

-i

Interactive prompt

Ask before overwrite. Appropriate for a human session, but unsuitable for unattended automation.

-a

Archive mode

Recursively copy a tree while preserving as much structure and metadata as practical.

-v

Verbose evidence

Print source and destination names so an operator can review what occurred.

For deployment automation, never depend on a shell alias such as cp='cp -i'. Scripts run in different environments. State every required option in the script and validate the destination independently.

4. Move and rename: same command, different mechanics

mv renames or relocates filesystem entries. Within one filesystem, a move is often a metadata operation: the directory entry changes while file data remains in place. Across filesystems, the implementation generally copies data and then removes the source after a successful copy.

cd -- "$workspace"

# Rename within one directory.
mv -v -- staging/app.conf staging/app.conf.candidate

# Move into an existing directory.
mv -v -- staging/app.conf.candidate archive/

# Refuse to overwrite an existing destination.
mv -vn -- source/app.conf archive/app.conf

# Verify the final locations.
find source staging archive -maxdepth 2 -printf '%y %p\n' | sort
Atomicity boundary

A same-filesystem rename can be atomic from the viewpoint of other processes, which makes it useful for publishing completed files. A cross-filesystem move cannot provide the same simple guarantee because data must be copied.

5. Removal unlinks names; it does not provide a recycle bin

rm removes directory entries. A normal command-line environment does not move them to a graphical trash folder. Recovery may be difficult or impossible, especially after storage blocks are reused. The safest removal is one whose exact target set was already printed and reviewed.

CommandTargetSafety characteristic
rm -- fileFile or symbolic linkFails for directories unless recursive mode is requested
rm -i -- fileInteractive file removalPrompts before each target; human-only safeguard
rmdir -- dirEmpty directoryRefuses to remove a non-empty directory
rm -r -- dirDirectory treeRecursive and potentially destructive; preview first
rm -rf -- dirTree without promptsForceful automation tool, not a default troubleshooting response
target="$workspace/staging/source-snapshot"

# Preview the exact tree first.
printf 'Candidate removal tree:\n'
find "$target" -depth -printf '%y %p\n'

# Require the expected parent path before removal.
case "$target" in
  "$HOME/devops-academy/linux/chapter04/lesson01/staging/"*)
    rm -r -- "$target"
    ;;
  *)
    printf 'Refusing unexpected target: %s\n' "$target" >&2
    exit 64
    ;;
esac

# Remove an empty directory with the narrower command.
rmdir -- "$workspace/staging"

6. Safer patterns for interactive and automated work

01Orient

Run pwd -P and list the parent directory. Verify that variables are non-empty and point below an expected root.

02Preview

Use printf '%q\n', find, or a command’s dry-run facility before a bulk change.

03Bound

Operate on an explicit directory or array rather than an unreviewed wildcard from an unknown location.

04Protect

Use no-clobber behavior, versioned backups, snapshots, or a staging directory when overwrites are possible.

05Verify

Check existence, type, size, checksum, or content after the operation. A zero exit code is necessary but may not prove the intended result.

7. Hands-on lab: assemble and publish a release directory

This lab creates a miniature release workspace, builds a candidate directory, verifies it, publishes it through a rename, and removes only a disposable build area.

set -u
root="$HOME/devops-academy/linux/chapter04/lesson01-release"
source_dir="$root/source"
build_dir="$root/build/release-1.0.0"
releases_dir="$root/releases"

mkdir -p -- "$source_dir" "$build_dir" "$releases_dir"
printf '%s\n' '<h1>DevOps Academy demo</h1>' > "$source_dir/index.html"
printf '%s\n' 'version=1.0.0' > "$source_dir/release.env"

cp -a -- "$source_dir/." "$build_dir/"
printf '%s  %s\n' \
  "$(sha256sum "$build_dir/index.html" | awk '{print $1}')" \
  'index.html' > "$build_dir/SHA256SUMS"

# Verify required files before publication.
for required in index.html release.env SHA256SUMS; do
  test -f "$build_dir/$required" || {
    printf 'missing required file: %s\n' "$required" >&2
    exit 1
  }
done

published="$releases_dir/1.0.0"
test ! -e "$published" || {
  printf 'release already exists: %s\n' "$published" >&2
  exit 1
}
mv -- "$build_dir" "$published"

printf 'Published release:\n'
find "$published" -maxdepth 1 -type f -printf '%f\n' | sort

# Remove only the now-empty build parent.
rmdir -- "$root/build"
printf 'Workspace retained at %s\n' "$root"

Verification checklist

8. Common file-operation mistakes

Assuming the destination meaning

cp source target behaves differently when target is an existing directory. Inspect it before running the command.

Using sudo to bypass ownership problems

This can create root-owned files inside a user workspace. Diagnose identity and permissions instead.

Trusting aliases as safeguards

Aliases may not exist in scripts, CI jobs, containers, or another operator’s shell.

Combining wildcard expansion with recursive force

The shell may produce a larger or different target set than expected. Preview expanded names and constrain the parent directory.

9. Knowledge check

Question 1. What does cp source destination do when the destination is an existing directory?

Question 2. Why can a same-filesystem mv be safer for publishing a completed file than copying directly into place?

Question 3. Why is rm -rf not an appropriate default response to a removal problem?

10. Summary

Controlled file operations begin with explicit paths and end with verification. mkdir and printf create structure and content; cp duplicates data; mv renames or relocates entries; rm and rmdir unlink names. No-clobber options, bounded targets, staging directories, and rollback paths turn fragile commands into operational procedures.

Next lesson

File Types, Metadata, stat, and file

You will inspect what a filesystem object is, how Linux records its metadata, and why a filename extension is not authoritative.

11. Further reading

  • GNU Coreutils manuals for mkdir, touch, cp, mv, rm, rmdir, install, and sha256sum.
  • Linux manual pages for rename, unlink, open, stat, and path_resolution.
  • POSIX specifications for cp, mv, rm, mkdir, and pathname handling.
  • Filesystem Hierarchy Standard — placement and purpose of system directories.
  • GNU Bash Reference Manual — quoting, expansion, exit status, and command execution.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.