Linux Copy Command: Copying Files From the Command Line

The pointing and clicking of copying many multiple files can quickly become tiresome. Fortunately, the Linux copy command offers a range of utilities to help developers save tons of time!
linux copy command alpharithms

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.

Zαck West
Full-Stack Software Engineer with 10+ years of experience. Expertise in developing distributed systems, implementing object-oriented models with a focus on semantic clarity, driving development with TDD, enhancing interfaces through thoughtful visual design, and developing deep learning agents.