CrackOps
Interview PrepTracksLinuxAWS LabSoonInterview RoomSoon
Sign inStart free
CrackOps

Interview prep for the people who keep production up.

[email protected]
ProductInterview PrepTracksDashboardInterview Room
RolesDevOpsSREPlatformCloud
CompanyAboutContactPrivacyTerms
© CrackOps
Linux / File & Directory Management / cp

cp

Copy files and directories

Beginneressentialfilesystembackup

cp copies files, and with -r whole directory trees. The options decide what survives the copy: plain cp gives you a new file owned by you with a fresh timestamp, while -a keeps permissions, owners, timestamps and symlinks, which is what you want for backups.

Syntaxcp [OPTION]... SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY

Watch it run

You are about to change a production config and want a copy you can restore in seconds.

devops@devops-lab: /etc/nginx — zsh — 96×28
➜ /etc/nginx
Step 1 of 4
cp nginx.conf nginx.conf.bak

Reading nginx.conf is allowed, but creating a new file needs write permission on the directory /etc/nginx, which only root has.

Anatomy of a command

$
prefixsudo

Run as root: needed to write under /etc and to keep root ownership on the copies.

How it works

For each file cp opens the source, stats it, creates the destination with open(O_CREAT|O_WRONLY|O_TRUNC) and copies the bytes. Modern coreutils first tries copy_file_range(), or a reflink (FICLONE) on filesystems like Btrfs and XFS, so the kernel moves the data without it passing through cp's memory, and it keeps holes in sparse files. The new file is a new inode: by default it's owned by you, its mode is the source's mode filtered by your umask, and its timestamps are now. -p or -a add fchown(), fchmod() and utimensat() calls to copy the metadata (keeping the owner needs root). -r walks the tree, creating directories with mkdir() and recreating symlinks as symlinks with -a. If DEST is an existing directory, the copy goes inside it; that one rule explains most surprises.

Options you'll actually use

-r, -RCopy directories recursively
-aArchive: -r plus keep mode, owner, times, links, ACLs, xattrs
-pPreserve mode, ownership and timestamps
-iAsk before overwriting an existing file
-uCopy only when the source is newer than the destination
-vPrint each file as it is copied
--backup=numberedKeep the old destination as file.~1~, file.~2~ ...
-LFollow symlinks in the source and copy what they point to
-l / -sMake hard links / symlinks instead of copying data
-t DIRTarget directory first, handy with xargs and find
--reflink=autoInstant copy-on-write clone where the filesystem supports it

Common mistakes

cp -r src/ backup/ twice and expecting the second run to refresh backup

On the second run backup/ exists, so cp copies src inside it: backup/src/. You end up with nested, stale copies.

cp -rT src backup or cp -a src/. backup/ or use rsync -a src/ backup/
sudo cp -r /var/www/site /new/disk/ for a migration

-r alone resets owners to root, timestamps to now and follows no ACLs; the app user loses write access.

sudo cp -a /var/www/site /new/disk/ (or rsync -aHAX)
cp *.log /backup/ in a directory with 300,000 logs

The shell expands the glob first and fails with 'Argument list too long'.

find . -name '*.log' -exec cp -t /backup/ {} +
Copying a database's data files while it's running

cp copies files one after another; the database keeps writing, so the copy is inconsistent and may not start.

Use the database's dump/backup tool (pg_dump, mysqldump) or a filesystem snapshot

Interview questions

Practice

Try these on a Linux machine of your own. Each task has a hint and a solution.

  1. 1

    Make a dated backup of ~/app/config/app.yaml next to the original, keeping its timestamp.

  2. 2

    Copy the whole ~/app directory to ~/backups/app-copy with everything preserved, and check the copy kept .env's mode.

  3. 3

    Run cp -r ~/app/config ~/backups/cfg twice and look at what happened. Then do it so the second run refreshes instead of nesting.

Related commands

mvMove or rename files and directoriesrsyncSync files and directories efficientlylnCreate hard links and symbolic linkstarBundle files into an archive and extract them
PreviouspwdNextmv
Linux / File & Directory Management / cp

cp

Copy files and directories

Beginneressentialfilesystembackup

cp copies files, and with -r whole directory trees. The options decide what survives the copy: plain cp gives you a new file owned by you with a fresh timestamp, while -a keeps permissions, owners, timestamps and symlinks, which is what you want for backups.

Syntaxcp [OPTION]... SOURCE DEST cp [OPTION]... SOURCE... DIRECTORY

Watch it run

You are about to change a production config and want a copy you can restore in seconds.

devops@devops-lab: /etc/nginx — zsh — 96×28
➜ /etc/nginx
Step 1 of 4
cp nginx.conf nginx.conf.bak

Reading nginx.conf is allowed, but creating a new file needs write permission on the directory /etc/nginx, which only root has.

Anatomy of a command

$
prefixsudo

Run as root: needed to write under /etc and to keep root ownership on the copies.

How it works

For each file cp opens the source, stats it, creates the destination with open(O_CREAT|O_WRONLY|O_TRUNC) and copies the bytes. Modern coreutils first tries copy_file_range(), or a reflink (FICLONE) on filesystems like Btrfs and XFS, so the kernel moves the data without it passing through cp's memory, and it keeps holes in sparse files. The new file is a new inode: by default it's owned by you, its mode is the source's mode filtered by your umask, and its timestamps are now. -p or -a add fchown(), fchmod() and utimensat() calls to copy the metadata (keeping the owner needs root). -r walks the tree, creating directories with mkdir() and recreating symlinks as symlinks with -a. If DEST is an existing directory, the copy goes inside it; that one rule explains most surprises.

Options you'll actually use

-r, -RCopy directories recursively
-aArchive: -r plus keep mode, owner, times, links, ACLs, xattrs
-pPreserve mode, ownership and timestamps
-iAsk before overwriting an existing file
-uCopy only when the source is newer than the destination
-vPrint each file as it is copied
--backup=numberedKeep the old destination as file.~1~, file.~2~ ...
-LFollow symlinks in the source and copy what they point to
-l / -sMake hard links / symlinks instead of copying data
-t DIRTarget directory first, handy with xargs and find
--reflink=autoInstant copy-on-write clone where the filesystem supports it

Common mistakes

cp -r src/ backup/ twice and expecting the second run to refresh backup

On the second run backup/ exists, so cp copies src inside it: backup/src/. You end up with nested, stale copies.

cp -rT src backup or cp -a src/. backup/ or use rsync -a src/ backup/
sudo cp -r /var/www/site /new/disk/ for a migration

-r alone resets owners to root, timestamps to now and follows no ACLs; the app user loses write access.

sudo cp -a /var/www/site /new/disk/ (or rsync -aHAX)
cp *.log /backup/ in a directory with 300,000 logs

The shell expands the glob first and fails with 'Argument list too long'.

find . -name '*.log' -exec cp -t /backup/ {} +
Copying a database's data files while it's running

cp copies files one after another; the database keeps writing, so the copy is inconsistent and may not start.

Use the database's dump/backup tool (pg_dump, mysqldump) or a filesystem snapshot

Interview questions

Practice

Try these on a Linux machine of your own. Each task has a hint and a solution.

  1. 1

    Make a dated backup of ~/app/config/app.yaml next to the original, keeping its timestamp.

  2. 2

    Copy the whole ~/app directory to ~/backups/app-copy with everything preserved, and check the copy kept .env's mode.

  3. 3

    Run cp -r ~/app/config ~/backups/cfg twice and look at what happened. Then do it so the second run refreshes instead of nesting.

Related commands

mvMove or rename files and directoriesrsyncSync files and directories efficientlylnCreate hard links and symbolic linkstarBundle files into an archive and extract them
PreviouspwdNextmv