Linux-based systems offer a host of shell commands that can help users and developers power through tasks. The copy (cp) command provides a convenient command-line-based means of copying files. In this short article, we’ll discuss how to copy all files in a directory in a Linux-based operating system.
Quick Intro: The Copy Function
The Copy command (cp
) is used to copy files, groups of files, or even entire directories. Via various options, the copy command can be used to copy one or multiple files or directories to a source file, files, or directory. The copy command comes with many useful options as well. Among the many optional features, the copy command allows users to do the following:
- Create a backup of the destination file
- Force copy for occasions when user privileges are restricted
- Recursively copy all files and subdirectories
- Preserve file attributes of source files when copying
- Supports wildcard use for source file specifications
These are a few of the many options available via the copy command. This command can help perform powerful-yet-fundamental actions with ease. This article will walk through several uses of the copy function ranging from basic use to the use of some more interesting options. First, let’s take a look at a sample directory containing some files and subdirectories which we can use as our sandbox.
Sample Directory & Files
We have a basic directory structure with some subdirectories and files scattered throughout. Below is the structure from which we will start our copy command discussion:
. └── copy-examples/ ├── a.txt ├── subdir1/ │ └── b.txt └── subdir2/ ├── c.txt ├── subdir2_subdir1/ │ └── d.txt └── subdir2_subdir2/ └── e.txt
Basic Syntax
As we progress through this article we’ll use the copy command with various options and arguments. However, the base syntax for this command is as follows:
$ cp [source_file] [destination_file]
The $
in this case, representing our use of the Linux Shell. This syntax will vary slightly as we copy multiple files, copy to and from directories, and start adding flags for things like preserving file attributes. This article introduces the copy command via examples of simple, common-case usage. Check out Linux.org’s documentation for a full listing of commands and options.
Copy a Single File
Copying a single file from a source to a destination is the canonical use case for the Linux copy command. To copy a single file one need simply enter it into the shell cp
, followed by the file to copy, followed by the name of the destination file. Run from the copy-examples
directory, the a.txt
file can be copied as a-copy.txt
by the following command:
$ cp a.txt a-copy.txt
Entering an ls command (show files in the current directory) produces the following output now: a-copy.txt a.txt subdir1 subdir2
indicating our file was successfully copied.
Copy Files to Another Directory
Copying a file into its existing directory isn’t always desirable behavior. In many cases, one might want to copy a file to another directory or copy a file from another directory. Below is the command needed to copy a.txt
from its current directory to the subdir1
directory:
$ cp a.txt subdir1
Notice we didn’t actually specify the full filename of the output file. The copy command doesn’t require re-specifying the destination file name, provided an argument is passed for the directory. Passing .
as the destination target (indicating the current directory) will produce the following error message:
$ cp: 'a.txt' and './a.txt' are the same file
Copy Files From Another Directory
Copying files from another directory is often something that developers and users need to do. The Linux copy command allows one to specify a directory other than the current working directory from which a source file can be used to copy to a destination. For example, let us copy c.txt
from subdir2
to the root of our project directory. This can be done via the following command:
$ cp subdir2/c.txt .
This creates a copy of c.txt
in our current working directory. This cp command can also copy from another directory to another directory. For example, let’s create another copy of the subdir_2/c.txt
file and place it in the subdir1
directory:
$ cp subdir_2/c.txt subdir1/c.txt
We can confirm the success of this action via a $ ls subdir1
command that produces the following output:
a.txt b.txt c.txt
The copy command does not support the creation of non-existing directories. For example, $ cp a.txt subdir_3/a.txt
will produce the following error message:
cp: cannot create regular file 'subdir_3/a.txt': No such file or directory
Passing in the --parents
flag can copy existing file structures from a source file into a target directory — but doesn’t allow the creation of novel new directory names.
Copying Multiple Files
Our subdir1
has started to accumulate quite a few files. We now have an a.txt
, b.txt
, and c.txt
file in this directory. Copying each of these files manually would require the issuance of three separate cp commands — and we all know programmers are too lazy for that! Fortunately, we can copy all these files using the following command:
$ cp subdir1/a.txt subdir1/b.txt subdir1/c.txt subdir2/subdir2_subdir1
Running a ls
command on the subdir2/subdir2_subdir1
directory lets us know all went according to our plan. This works, but the syntax is starting to get clunky. Fortunately, there are several approaches that can help simplify our syntax. The first is to use wildcard notation:
$ cp subdir2/subdir2_subdir1/*.txt subdir2/subdir2_subdir2
This instructs the copy program to copy all files ending in .txt
from the subdir2/subdir2_subdir1
directory, into which we just copied several files, to the subdir2/subdir2_subdir2
directory in which the only existing file was e.txt
. Again, running an ls
command can confirm our success.
Copying A Directory
The copy command supports the copy of entire directories as well. However, this command works a bit differently than expected. Let’s try to copy the subdir2
directory and name the copy subdir2_copy
with the following command:
$ cp subdir2 subdir2_copy
This results in the following message being printed to the terminal window:
cp: -r not specified; omitting directory 'subdir2'
Running the $ cp --help
command displays the following message on a Linux-based OS:
-R, -r, --recursive copy directories recursively
The r flag, commonly used to indicate recursive handling, is required for the copy command to handle directory copying. This will ensure all files and subdirectories are copied as well. Let’s try to copy the subdir2 directory again with the following command:
$ cp -r -v subdir2 subdir2_copy
The -v
flag instructs the copy command to run in verbose mode via which every action is described in the console. The output is as follows:
'subdir2' -> 'subdir2_copy' 'subdir2/c.txt' -> 'subdir2_copy/c.txt' 'subdir2/subdir2_subdir2' -> 'subdir2_copy/subdir2_subdir2' 'subdir2/subdir2_subdir2/b.txt' -> 'subdir2_copy/subdir2_subdir2/b.txt' 'subdir2/subdir2_subdir2/c.txt' -> 'subdir2_copy/subdir2_subdir2/c.txt' 'subdir2/subdir2_subdir2/d.txt' -> 'subdir2_copy/subdir2_subdir2/d.txt' 'subdir2/subdir2_subdir2/a.txt' -> 'subdir2_copy/subdir2_subdir2/a.txt' 'subdir2/subdir2_subdir2/e.txt' -> 'subdir2_copy/subdir2_subdir2/e.txt' 'subdir2/subdir2_subdir1' -> 'subdir2_copy/subdir2_subdir1' 'subdir2/subdir2_subdir1/d.txt' -> 'subdir2_copy/subdir2_subdir1/d.txt' 'subdir2/subdir2_subdir1/c.txt' -> 'subdir2_copy/subdir2_subdir1/c.txt' 'subdir2/subdir2_subdir1/b.txt' -> 'subdir2_copy/subdir2_subdir1/b.txt' 'subdir2/subdir2_subdir1/a.txt' -> 'subdir2_copy/subdir2_subdir1/a.txt'
As evidenced by the output courtesy of the -r
flag, we can confirm that all files and subdirectories of subdir2 were copied into the newly-created subdir2_copy
.
Recapping
We have done quite a bit of copying so far and it’s easy to lose track of which files are where without a graphical display. Below is an ASCII representation of our project folder after running all of the above copy commands:
. └── copy-examples/ ├── a-copy.txt ├── a.txt ├── c.txt ├── subdir1/ │ ├── a.txt │ ├── b.txt │ └── c.txt ├── subdir2/ │ ├── c.txt │ ├── subdir2_subdir1/ │ │ ├── a.txt │ │ ├── b.txt │ │ ├── c.txt │ │ └── d.txt │ └── subdir2_subdir2/ │ ├── a.txt │ ├── b.txt │ ├── c.txt │ ├── d.txt │ └── e.txt └── subdir2_copy/ ├── c.txt ├── subdir2_subdir1/ │ ├── a.txt │ ├── b.txt │ ├── c.txt │ └── d.txt └── subdir2_subdir2/ ├── a.txt ├── b.txt ├── c.txt ├── d.txt └── e.txt
This visualization shows all the random copying we’ve done as well as the larger recursive copy function in the most recent section. Note here the names of all the files and subdirectories within out subdir2_copy
are matches to the source files. The only naming that changed was for the parent directory.
Note: A Python script was used to print out a visual representation of all the directories here such that an ASCII version could easily be formatted. That Python code is available as a gist on Github. Usage is as follows:
$ python3 print_dir_tree.py name-of-directory
Final Thoughts
The copy command in Linux is a powerful command line utility that makes copying single files, multiple files, or even entire directories simple. Advanced use of this tool includes selective file copying, force copying of read-protected files, and even the creation of symlinks instead of physical files.
Command line utilities like copy
can be difficult to learn at first but invaluable for developers of all specialties. This tool might seem trivial in the age of GUIs but when one needs to perform an action such as copying any file matching a glob pattern — the copy command shines.