Build a clear mental model of paths, files and links, then use it to assemble a small release workspace without modifying an existing deployment.
Series: Introduction · Part 1 of 6 · Next: text processing
Applies to: Bash and GNU Coreutils on Linux. Outputs below are illustrative or derived from the supplied fixture.
The subsystem: paths, directories and inodes
Linux presents a directory tree rooted at /. A pathname tells the filesystem how to find an object. The object’s metadata lives in an inode; a directory associates names with inode numbers. Mounted filesystems join this tree, so two neighboring paths can reside on different disks.
These commands solve ordinary operational problems: locating a configuration file, staging an artifact, moving a completed report or creating a stable reference to a versioned directory. Work inside your own lab directory:
lab=$(mktemp -d)
cd -- "$lab"
printf 'release=1\n' > app.conf
The shell variable exists in this session only. Commands below assume you remain in that directory.
pwd: confirm your location
pwd -P
This prints the physical path, resolving symbolic links in the current directory. Expect a path such as /tmp/tmp.ABC123. Use it before an operation involving relative paths; ./app.conf means the file under the current directory, not a file under your home directory.
ls: inspect names and metadata
ls -la -- .
ls -ld -- app.conf
-a includes dot-prefixed names, while -l displays permissions, ownership, size and timestamps. -d lists a directory entry itself rather than its contents. A regular file’s mode can look like -rw-r--r--; the actual owner and timestamp vary. Use ls for human inspection, not as a filename parser in scripts: spaces and newlines can be valid filename characters.
cd: change the shell’s working directory
mkdir -- workspace
cd -- workspace
pwd
cd ..
cd is a builtin because it must change the current shell’s directory. Running it inside a separate script does not move the calling terminal. In a script, stop if a required cd fails; otherwise subsequent relative-path operations may happen somewhere unintended.
mkdir: create a directory structure
mkdir -p -- releases/v1 reports
-p creates missing parent directories and accepts an already-existing directory. It does not prove the directory has the ownership or permissions your application needs. For a private work area, set umask 077 before creating files; Part 3 explains that policy.
rmdir: remove only an empty directory
mkdir -- unused
rmdir -- unused
There is normally no output on success. If unused contains anything, removal fails. That refusal is useful when the intention is “remove the empty placeholder,” rather than “delete whatever happens to be inside this path.”
touch: create a file or change its timestamps
touch -- deployment.ready
A missing regular file is created empty. An existing file retains its contents but normally receives new access and modification times. A timestamp marker can support a simple workflow, but it is not proof that a deployment completed or that a file’s contents changed.
cp: make a separate copy
cp -- app.conf releases/v1/app.conf
cp -a -- releases/v1 releases/v1-review
The first command copies one file. GNU cp -a copies a directory tree and attempts to preserve relevant attributes. Plain cp may overwrite an existing destination, so inspect targets first; interactive cp -i can ask before overwriting when working manually. Copying a live data directory does not by itself produce a consistent database backup.
mv: rename or relocate an entry
mv -- deployment.ready release.ready
A move within one filesystem is typically a rename. A move across filesystems involves copying and removing the source, so do not assume every mv provides an atomic deployment. Existing destinations may be overwritten. In a release process, use a new destination and retain the previously active release.
rm: remove a directory entry deliberately
Create a disposable fixture before trying removal:
touch -- discard.me
rm -i -- discard.me
GNU rm -i asks before removal; answer y only for this fixture. There is normally no trash bin or built-in undo. The combination -r traverses directories and -f suppresses prompts and some errors. Our outline mentions rm -rf, but routine release preparation does not need it. Use an explicit retention policy and a reviewed path before deleting operational artifacts.
ln: create another name or a symbolic reference
ln -- app.conf app.conf.hardlink
ln -s -- releases/v1 current
ls -ld -- current
A hard link is another directory entry for the same inode and generally cannot cross filesystems. A symbolic link stores a path; current -> releases/v1 is resolved relative to the link’s directory. Updating the target through either hard-link name changes the same file. A symbolic link can become dangling if its target disappears.
Practical script: assemble an isolated release handover
An engineer needs to hand a configuration artifact to a reviewer. This script accepts one readable regular file, creates a private temporary workspace, stages the file, marks it ready and creates a relative current link. It never changes the active application or deletes a previous release.
Save as stage-release.sh; run bash stage-release.sh ./app.conf with a non-sensitive lab file. It uses mktemp and printf as supporting utilities.
#!/usr/bin/env bash
set -euo pipefail
umask 077
if (( $# != 1 )) || [[ ! -f $1 || ! -r $1 ]]; then
printf 'Usage: bash stage-release.sh READABLE_FILE\n' >&2
exit 2
fi
source_file=$1
workspace=$(mktemp -d)
mkdir -p -- "$workspace/releases/v1" "$workspace/review/empty"
cp -- "$source_file" "$workspace/releases/v1/artifact"
cp -- "$workspace/releases/v1/artifact" "$workspace/review/artifact.pending"
mv -- "$workspace/review/artifact.pending" "$workspace/review/artifact.ready"
touch -- "$workspace/releases/v1/READY"
rmdir -- "$workspace/review/empty"
ln -s -- releases/v1 "$workspace/current"
cd -- "$workspace"
printf 'Review workspace: '
pwd -P
ls -ld -- current releases/v1 review/artifact.ready
Verify that current points to releases/v1 and the review artifact exists. The workspace remains available for inspection. This illustrates staging, not a complete deployment protocol: it does not validate application configuration, retain database state, activate production or implement rollback.
Troubleshooting and references
“Permission denied” means inspect access to the file and parent directories; do not immediately rerun the whole script as root. “File exists” from ln means a destination already exists and needs review. An unexpected pwd result means stop and resolve the path before changing files.
References: GNU file operations, GNU directory listing, GNU link command, Bash directory builtins.