Chapter 09Lesson 02~90 minutes

Creating, Copying, Moving, and Removing Content

Filesystem mutation must be explicit about destinations, recursion, overwrites, and destructive scope. A command that is harmless interactively can be catastrophic when fed the wrong variable in automation.

BeginnerFilesystemHands-on lab

Learning objectives

By the end of this lesson

  • Create directories idempotently.
  • Copy and move with explicit destination semantics.
  • Stage content before promotion.
  • Constrain destructive deletion.
  • Use dry-run and installation patterns safely.

1. mkdir -p expresses a convergent directory goal

workspace="$HOME/builds/api"
mkdir -p -- "$workspace"

This is generally better than checking for existence and then creating the directory in a separate step.

2. Copy semantics depend on the destination

cp -- source.conf backup.conf
cp -- artifact.tar.gz releases/

A directory destination preserves the source basename; a file destination names the new copy. Scripts should know which interpretation they require.

3. Recursive copy requires explicit testing

mkdir -p config-live
cp -R -- config-template/. config-live/

The exact source spelling can change whether the directory itself or only its contents are copied.

Stage complex trees

For deployments, build a staging tree, validate it, and then promote it instead of editing the live tree piecemeal.

4. Make overwrite policy explicit

if [[ -e $destination ]]; then
  printf 'destination exists: %s\n' "$destination" >&2
  exit 1
fi
cp -- "$source" "$destination"

Interactive confirmation flags are not a reliable non-interactive automation policy.

5. mv is useful for promotion

mv -- staged.conf live.conf

Within one filesystem, rename-like moves can efficiently switch pathname references. Cross-filesystem moves may require copy-and-remove behavior instead.

6. rm deserves stronger validation than ordinary commands

target="$workspace/cache"

if [[ -z $target || $target == / ]]; then
  printf 'refusing dangerous target\n' >&2
  exit 1
fi

rm -rf -- "$target"
Destructive boundary

Do not feed loosely constructed or unvalidated paths into recursive rm.

7. Constrain deletion to a managed root

root="$HOME/devops-academy/work"
target="$root/cache"

case $target in
  "$root"/*) rm -rf -- "$target" ;;
  *) printf 'outside managed root\n' >&2; exit 1 ;;
esac

This is a useful policy check but not a complete defense against all symlink/canonicalization issues.

8. install combines copying with mode management

install -d -m 0755 -- "$HOME/.local/bin"
install -m 0755 -- deployctl "$HOME/.local/bin/deployctl"

This can make packaging-style operations clearer than a copy followed by a separate chmod.

9. Destructive workflows benefit from dry-run

remove_path() {
  local target=$1
  if [[ $dry_run == true ]]; then
    printf 'DRY-RUN: rm -rf -- %q\n' "$target"
  else
    rm -rf -- "$target"
  fi
}

Dry-run must bypass the real mutation.

10. Hands-on lab: stage and promote content

mkdir -p "$HOME/devops-academy/bash/chapter09/lesson02"
cd "$HOME/devops-academy/bash/chapter09/lesson02"

rm -rf -- staging live live.new live.old
mkdir -p -- staging live

printf 'version=2\n' > staging/app.conf
printf 'feature=true\n' > staging/feature.conf

mkdir -- live.new
cp -R -- staging/. live.new/

mv -- live live.old
mv -- live.new live

printf '%s\n' '--- live files ---'
find live -maxdepth 1 -type f -print

rm -rf -- live.old

Verification checklist

11. Knowledge check

Question 1. Why use mkdir -p?

Question 2. Why is recursive rm dangerous?

Question 3. What does install add beyond copying?

Question 4. Why can move/rename be useful for promotion?

12. Summary

Filesystem mutation should be explicit about destinations, recursion, overwrite, and deletion. Prefer staging, validated destructive roots, quoted operands, idempotent directory creation, and real dry-run behavior.

13. Further reading

  • GNU Coreutils manuals — mkdir, cp, mv, rm, install.
  • POSIX filesystem utility specifications.
  • rsync documentation for tree synchronization.
  • ShellCheck documentation — destructive path handling.
Next lesson

find, xargs, and Null-Delimited Workflows

Continue Chapter 9 by building safer, more predictable filesystem automation.

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.