To copy files in Linux and most other UNIX operating systems, you will use the cp command.  This command allows you to copy a single or multiple files from one directory to another.  There are many options to the cp command and here we will explore those options and also give some examples.

Basic Copy

To simply copy a file into the same directory:

cp file.txt filecopy.txt

To copy a file to another location, you simple enter the command cp, then the source file to copy from, and the target file (with path) to which you would like to copy it.

cp /var/tmp/file.txt /home/savona/file.txt

The above example simply copies files.txt from /var/tmp/ to /home/savona/

Copy Multiple Files

To copy multiple files, you can simple add multiple source files like so:

cp /var/tmp/file.txt /var/tmp/file1.txt /var/tmp/file2.txt /home/savona/

If the files are in the current working directory, you do not need to specify the full path.  For example:

cd /var/tmp/
cp file.txt file1.txt file2.txt /home/savona/

Verbose Output

Using verbose output if handy when copying a lot of files, or when scripting.  Using the -v option will give you feedback on exactly what is being done.

Here is an example of a successful copy using the verbose mode:

$ cp -v file.txt resume.txt
‘file.txt’ -> ‘resume.txt’

Recursively Copy Files

Using the -r or recursive option will allow you to copy directories and subdirectories recursively.  For example, if we had a directory called “testcopy” that contained a subdirectory and files in each, you can copy them all recursively like so:

NOTE: I used the -v (verbose) option with the -r (recursive) option to show you the results.

$ cp -rv /var/tmp/testcopy /tmp/
‘/var/tmp/testcopy’ -> ‘/tmp/testcopy’
‘/var/tmp/testcopy/file.txt’ -> ‘/tmp/testcopy/file.txt’
‘/var/tmp/testcopy/file1.txt’ -> ‘/tmp/testcopy/file1.txt’
‘/var/tmp/testcopy/testsubdir’ -> ‘/tmp/testcopy/testsubdir’
‘/var/tmp/testcopy/testsubdir/anotherfile2.txt’ -> ‘/tmp/testcopy/testsubdir/anotherfile2.txt’
‘/var/tmp/testcopy/testsubdir/anotherfile1.txt’ -> ‘/tmp/testcopy/testsubdir/anotherfile1.txt’
‘/var/tmp/testcopy/testsubdir/anotherfile.txt’ -> ‘/tmp/testcopy/testsubdir/anotherfile.txt’
‘/var/tmp/testcopy/file2.txt’ -> ‘/tmp/testcopy/file2.txt’

As you can see, the cp command recursively copied all files and folders under the specified target directory.

Create Parent Directories as Needed

The --parents option allows you to move a file from one nested directory to another and recreate the parent directories. For example, let's say you have the following file:

~/Pictures/2013/7-4-2013/July4Family.mp4

You want to copy it to the Videos folder but want to retain the file structure of <year> / <date> / filename. You can use the --parents option to copy the file.

Example:

$ cp -v --parents 2013/7-4-2013/July4Family.mp4 /home/savona/Videos/
2013 -> /home/savona/Videos/2013
2013/7-4-2013 -> /home/savona/Videos/2013/7-4-2013
'2013/7-4-2013/July4Family.mp4' -> '/home/savona/Videos/2013/7-4-2013/July4Family.mp4'

As you can see in the example output above, the cp command first created the parent directories (in bold) and then copied the file.

Preserve File Attributes when Copying

The output below shows the file (notice timestamp) to be copied.

$ ls -lrt
total 4
-rw-rw-r--. 1 savona savona 53 Jul 14 07:25 savonatest.txt

Now we will copy it without the -p (preserve) option, and check the timestamp (Notice timestamp change):

$ cp savonatest.txt testnopreserve.txt
$ ls -lrt
total 8
-rw-rw-r--. 1 savona savona 53 Jul 14 07:25 savonatest.txt
-rw-rw-r--. 1 savona savona 53 Jul 14 07:28 testnopreserve.txt

Now we will copy the file with the -p (preserve) option, notice the timestamp is preserved:

$ cp -p savonatest.txt testpreserve.txt
$ ls -lrt
total 12
-rw-rw-r--. 1 savona savona 53 Jul 14 07:25 testpreserve.txt
-rw-rw-r--. 1 savona savona 53 Jul 14 07:25 savonatest.txt
-rw-rw-r--. 1 savona savona 53 Jul 14 07:28 testnopreserve.txt

This was a simple example, but using the preserve option allows you to preserve User and Group permissions, File Mode, Flags, Access time, Modification time, Access Controls Lists (ACLs), and Extended Attributes.

NOTE: PRESERVE FILE ATTRIBUTES MAY BE LIMITED BY YOUR PERMISSIONS.

Wildcards

The star wildcard can represent zero characters, any single character, or any string made up of multiple characters.

If you want to copy all files from your current directory to /var/tmp/ you can use this wildcard to represent all files.

cp * /var/tmp/

You can also use it to copy all like files.  For example if you wanted to copy all txt files from your currect directory to /var/tmp/.

cp *.txt /var/tmp/

For more information on Wildcards see our article "Standard Wildcards & Globbing Patterns in Linux".

Preserve SELinux Security Context

With the --preserve option, it is possible to copy a file and preserve the SELinux security context.

Let's see that the SELinux context of the /tmp/testfile.txt is:

ls -Z testfile.txt 
system_u:object_r:tmp_t:s0 testfile.txt

Now let's move it and preserve the security context.

cp --preserve=context /tmp/testfile.txt /home/savona/destination.txt

Here we will see that it preserved the tmp object security context, even though other files are correctly labeled as user_home.

ls -lrtZ
-rw-rw-r--. 1 savona savona unconfined_u:object_r:user_home_t:s0 0 Feb 16 15:40 pink_floyd_lyrics.txt
-rw-rw-r--. 1 savona savona system_u:object_r:tmp_t:s0 61 Feb 16 15:50 destination.txt

Conclusion

The cp command is very flexible if you learn all the options. It may seem like a bit to remember, but using these options will save a lot of time.