To copy files or directories in Unix-based operating systems (Linux and MacOS), you use the
cp command is a relatively simple command, but its behavior changes slightly depending on the inputs (files vs directories) and the options you pass to it.
To view the documentation or manual for the
cp command, run
man cp at your terminal:
$ man cp NAME cp -- copy files SYNOPSIS cp [OPTIONS] source_file target_file cp [OPTIONS] source_file ... target_directory ...
The basic form of this command takes an input source (or sources) that you want to copy (files or directories) and a destination to copy the files or directories to:
cp [OPTIONS] source_file target_file
How to copy a file to the current directory
To copy a file, pass the file you want to copy and the path of where you want to copy the file to.
If you have a file named
a.txt, and you want a copy of that file named
$ ls a.txt $ cp a.txt b.txt $ ls a.txt b.txt
If you're not familiar with the
ls"lists" all the contents of a directory.
By default the
cp command uses your current directory as the path.
How to copy a file to another directory
To copy a file to a directory that is different from your current directory, you just need to pass the path of the other directory as the destination:
$ ls ../directory-1/ $ cp a.txt ../directory-1/ $ ls ../directory-1/ a.txt
cp command, the previously empty
directory-1 now contains the file
By default the copied file receives the name of the original file, but you can also optionally pass a file name as well:
$ cp a.txt ../directory-1/b.txt $ ls ../directory-1/ b.txt
How to copy multiple files to a directory
To copy more than one file at a time you can pass multiple input sources and a directory as destination:
$ ls ../directory-1/ $ cp first.txt second.txt ../directory-1/ $ ls ../directory-1/ first.txt second.txt
Here the two input sources (
second.txt) were both copied to the directory
Note: when passing multiple sources the last argument must be a directory.
How to copy a directory to another directory
If you try to pass a directory as the input source, you get this error:
$ cp directory-1 directory-2 cp: directory-1 is a directory (not copied).
To copy a directory, you need to add the
-R) flag—which is shorthand for
$ ls directory-1 a.txt $ cp -r directory-1 directory-2 $ ls directory-1 directory-2 $ ls directory-2 a.txt
directory-1 containing the file
a.txt is copied to a new directory called
directory-2—which now also contains the file
How to copy the entire directory vs the contents of the directory
There is an interesting edge case when you copy a directory: if the destination directory already exists, you can choose whether to copy the contents of the directory or the entire directory by adding or removing a trailing
/ from your input.
Here's the description from the
-R option of the
If source_file designates a directory, cp copies the directory and the entire subtree connected at that point. If the source_file ends in a /, the contents of the directory are copied rather than the directory itself.
If you want to copy just the contents of the directory into another directory, add a trailing
/ to your input.
If you want to copy the contents of the directory and the directory folder itself into another directory, don't add a trailing
$ ls directory-1 directory-2 $ ls directory-2 $ cp -r directory-1 directory-2 $ ls directory-2 directory-1 $ ls directory-2/directory-1 a.txt
Here you can see that because
directory-2 already exists—and the input source didn't have a trailing
/—both the contents of
directory-1 and the directory itself was copied into the destination.
How to prevent overwriting files with
By default, the
cp command will overwrite existing files:
$ cat a.txt A $ cat directory-1/a.txt B $ cp a.txt directory-1/a.txt $ cat directory-1/a.txt A
If you're not familiar with the
cator "concatenate" command, it prints the contents of a file.
There are two ways to prevent this.
The interactive flag
To be prompted when an overwrite is about to occur, you can add the
$ cp -i a.txt directory-1/a.txt overwrite directory-1/a.txt? (y/n [n])
The no-clobber flag
Or, to prevent overwrites without being prompted, you can add the
$ cat a.txt A $ cat directory-1/a.txt B $ cp -n a.txt directory-1/a.txt $ cat directory-1/a.txt B
Here you can see that thanks to the
-n flag the contents of
directory-1/a.txt were not overwritten.
There are many other useful options to pass to the
cp command: like
-v for "verbose" output or
-f for "force."
I highly encourage you to read through the
man page for all of the other useful options.
If you liked this tutorial, I also talk about topics like this on Twitter, and write about them on my site.