Copying files and directories is a common task when working in the Linux terminal. The most common way to do this is to use the cp Linux command. This command is included in all Linux distributions. It can copy files and directories, and preserve their attributes in Linux file systems.
In this article, we will take a deep dive into the cp command. We will explore its syntax, options, and provide the most common examples of its usage.
Table of Contents
Syntax and Options
The utility provides two types of syntax for copying files. The first one is to copy a file into another file with a specified name:
$ cp options /path/to/source/file /pathto/destination/file
The second one is to copy a file or directory with its original name into the specified directory:
$ cp options /path/to/source/file /pathto/destination/directory/
In the first case, the command will copy the source file into the destination file overriding it if it already exists. In the second case where the destination is a directory, the source file or directory will be copied into the directory with its original name.
The cp command has a lot of useful options that can help with less common copying scenarios. Here is the list of the most interesting ones:
- --attributes-only - copies only the mode and ownership of the file, without copying its contents;
- -b, --backup - creates a backup of files that already exist in the destination directory before overriding them;
- --copy-contents - copies contents of special files, such as FIFO and device files;
- -f, --force - attempts to remove the file in the destination before overwriting if it already exists;
- -i, --interactive - prompt user whether to override existing files;
- -n, --no-clobber - does not override existing files;
- -P, --no-dereference - copy symbolic links themselves, instead of copying files that they point to;
- -L, --dereference - copies files instead of copying symbolic links;
- -l, --link - creates hard links for files instead of copying them;
- --preserve - preserve specified attributes from the source file to the destination file. Available values: mode, ownership, time‐stamps, context, links, xattr, all;
- --no-preserve - do not preserve specified attributes;
- --parents - preserve the path specified in the source after copying to the destination, creates any missing directories in the process;
- -r, --recursive - copy directories and their contents recursively;
- --reflink - use Copy-on-Write when it is possible;
- -s, --symbolic-link - create symbolic links instead of copying files;
- -S, --suffix - specify a suffix for file backups;
- --sparse - configure copying sparse files;
- -t, --target-directory - treat the destination argument as a target directory and copy the source file or directory into it with preserving its original name. If the destination does not exist, the command will fail with an error message;
- -T, --no-target-directory - treat the destination argument as a regular file or directory. If the source is a file, it will be copied with a new file name. But if the source is a directory, then its contents will be copied into the destination;
- -u, --upgrade - copy files only if the source file is newer than the destination file or if the destination file does not exist;
- -x, --one-file-system - do not cross filesystem boundaries while copying recursively;
- -v, --verbose - display detailed information while copying;
In addition to the options listed above, some options combine several others with certain values. Here is the list of them:
- -p - preserve ownership, group, timestamps, and mode, equivalent to preserve=mode,ownership,timestamps;
- -d - copy symbolic and hard links as links, equivalent to --no-dereference --preserve=links;
- -a - archive mode, when all attributes and links structure are preserved and recursive copying is enabled, equivalent to --recursive --preserve=all, --no-dereference;
Now, that you know all the options, you are ready to practice. Let's look at some common examples of using cp in Linux.
Examples of Using cp
To provide examples of using cp in Linux in this article, I will create a few files and directories. You can create them too and try out the examples on your own machine. First of all, let's create three files named: file1, file2, and file3, a symbolic link link1 pointing to the file1 and a hard link hlink1 pointing to the file3, then create a directory with a name of source and file4, file5, file6 inside it. Finally, create the destination directory. Here are the commands for creating the links:
ln -s $(realpath file1) link1
ln file3 hlink1
In the end, I got this structure:
1. Copy File into Another File
The simplest way to copy a file is to copy one file into another location with a specified name. To do this just specify a new file name in a destination folder. For example, use the following command to copy the file named file1 to the ./destination folder with a new name file10:
cp file1 destination/file10
In the same way you can make a copy of the file in the same directory:
cp file1 file10
2. Copy File into a Directory
If you don't want to change filename or wish to copy multiple files, simply specify the destination folder for the files without specifying the filename. For example, use the following command to copy file1 into the ./destination folder with the original name:
cp file1 destination/
It is not necessary to place the slash at the end of the destination path. The utility can detect folders even without it.
3. Copy Folder into Folder
You have to use the -r (--recursive) option to copy folders. It is pretty simple to copy one folder into another when the destination folder exists. Use the following command to copy the source folder into the destination folder:
cp -r source destination
Alternatively, you can use the -t option to explicitly tell the command to consider the last argument as a directory for copying data:
cp -t file1 not_existent_destination
In this case, when the directory with the name of not_existent_destination does not exist you will get an error instead of unexpected behavior.
4. Copy Folder Contents into a Folder
If you want to copy the contents of one directory to another, you need to use the first syntax, described above. However, the command is the same as in the previous example. The utility will use the first syntax only if the destination directory does not exist. For example, use the following command to copy the contents of the source folder into the destination1 folder:
cp -r source destination1/
If the folder from the last argument exist, the source folder will be copied into it. But you can avoid this behavior by using the -T option:
cp -rT source destination/
In addition, you can explicitly specify that you are only interested in the content of the source folder by using an asterisk character. For example:
cp source/* destination
However, in this case, all hidden files will be skipped. Copying of sub-directories and their contents works in the same way.
5. Handling Existing Files
By default, the cp command overrides all existing files in the destination directory. If you want it to prompt before overriding every existing file, use the -i option. For example:
cp -i file1 destination
The -n option disables overriding existing files. So if the file already exists in the destination directory, it will not be copied:
cp -n file1 destination
In addition, you can make a backup for all existing files in destination folder using the -b or --backup option. For example, if you add the -b option, the utility will add ~ character in the end of each existing original file:
cp -b file1 destination
The --backup option allows to configure names for backup files. Here are all available values:
- none - disables backup;
- numbered - adds a number at the end of each file name;
- simple - adds the ~ character into the end of each file name, is used by default;
- existing - if the destination directory contains backup files, the command will use the same type of naming as for those backup files;
For example, if you want to use a number in the name of backup, use this command:
cp --backup=numbered file1 destination
Another option for handling existing files, which can be useful for large files is to override a file only if the version in the source folder is never or if the file does not exist in the destination folder. This can be done by using the -u or --upgrade option. For example:
cp -u source/* destination
6. Copying Links
Linux file systems can have symbolic and hard links. The cp command can copy them in different ways. By default, the cp command creates a copy of the file that a link points to, rather than copying the link itself. This applies to both: soft and hard links. If you want to copy symbolic links as links, use the -P option:
cp -P link1 destination
Hard links are handled differently. If you want to preserve hard links after copying, use the --preserve option with the value of the links:
cp --preserve=links hlink1 destination
7. Preserving Attributes
By default, cp updates timestamps and mode attributes for copied files. However, sometimes you may want to preserve the original values. You can use the --preserve option. Here are its possible values:
- mode - preserves flags that describe access permissions to write, read and execute, for user, group, and other, also covers additional bits that can be configured using chmod;
- ownership - the owner of the file and group;
- time-stamps - access, modify, change dates;
- context - SELinux context;
- links - preserve hard links;
- xattr - additional attributes that can be configured using the chattr command;
- all - everything listed above.
If want to preserve the original owner and group for the file copy, use the --preserve option with the value of mode,ownership or simply the -p option, like this:
cp -p source/* destination
If you want to preserve a whole filesystem structure, including links and timestamps use the -a option:
cp -a source/* destination
8. Using Copy-on-Write
Some modern Linux filesystems, such as Btrfs or ZFS support the Copy-on-Write feature. It allows not copying the file immediately. The file system simply writes all future modifications into another location. This feature works only in the same filesystem and highly increases the speed of file copying. The cp command has used it by default only since CoreUtils 9.0, but you can enable it manually in earlier versions using the --reflink option. Here are available values:
- always - always use Copy-on-Write and throw an error if it is not supported by filesystem;
- auto - use only if it is supported;
- never - do not use;
For example, to force use Copy-on-Write, add --reflink=always:
cp --reflink=always file3 destination
9. Copying Sparse Files
Sparse files contain sequences of zero bytes and these sequences are replaced by their description to save disk space. In can be useful for VirtualBox or Qemu images, which can contain a lot of empty space. By default, cp will create sparse files only if the original file is sparse. But you can configure it to make all files with zero sequences sparse using the --sparse option. The option has the following available values:
- auto - used by default;
- never - make sparse files not sparse;
- always - make files sparse when they contain a long enough sequence of zero bytes.
For example, you can create a 20 MB image from /dev/zero:
dd if=/dev/zero of=image1 count=20 bs=1M
If you copy this file into another directory with --sparse=always it will become sparse and take up much less disk space:
cp --sparse=always ./image1 destination
Wrapping Up
This article has explained how to use cp command Linux. Although this command has been around for a long time and does not provide a progress bar for copying large files, it supports many other useful features. But it supports a lot of other useful features. Almost all file-copying tasks in Linux can be accomplished using this command.