# Copying Files on Linux

Copying documents used to require a dedicated staff member in offices, and then a dedicated machine, and now it's a task computer users do without even giving it a second thought.
Copying data on a computer is such a trivial task that sometimes it happens without you even realising it, such as when dragging a file to an external drive.

The concept that digital entities are trivial to reproduce is pervasive, so most modern computerists don't think about the different ways available to them to duplicate their work.
And yet there are several different ways to copy a file on Linux, and each one has nuanced features that  might benefit you, depending on what you need to get done.
Here are all the ways to copy files on Linux, BSD, and Mac.

## Desktop

The most obvious way to copy a file is the way you've always copied files on computers: drag and drop.

On most Linux desktops, dragging and dropping from one local folder to another local folder *moves* a file by default.
You can change this to a copy operation by holding down the **Control** key after you have started dragging the file.
Your cursor may have an indicator, such as a plus sign, to show that you are in copy mode.

![Copying a file](copy-nautilus.jpg)

If a file exists on a remote system, whether it's a web server or just another computer on your own network that you are accessing through a file sharing protocol, the default action is often to copy, not move, the file.


## Desktop menu

If you find dragging and dropping files around your desktop imprecise or clumsy or just too much time away from your keyboard, you can usually copy a file using the right-click menu.
This depends on the file manager you use, but generally a right-click produces a contextual menu with common actions in it.
The copy action stores the [file path](https://opensource.com/article/19/7/understanding-file-paths-and-how-use-them) (where the file exists on your system) in your clipboard so that you can then "paste" the file somewhere else.

![Copying a file from the context menu](copy-file-menu.jpg)

You're not actually copying the contents of the file to your clipboard between the copy and paste action; what actually happens when you paste is your file manager looks at the file path you copied, and then runs a copy command on the file located at that path to the path you are pasting into.


## The cp command

The obvious terminal-based equivalent to copying and pasting a file on the desktop is the [cp](link to my article about cp command) command.
It copies files and directories, and is relatively straight-forward.
It uses the familiar *source* and *target* (strictly in that order) syntax, so to copy a file called ``example.txt`` into your ``Documents`` directory:

```
$ cp example.txt ~/Documents
```

Just like when you drag and drop a file onto a folder icon to copy the file into it, this doesn't replace ``Documents`` with ``example.txt``.
Instead, ``cp`` detects that ``Documents`` is a folder, and knows to place the copy of ``example.txt`` into it.

You can also, conveniently, rename the file as you copy it:

```
$ cp example.txt ~/Documents/example_copy.txt
```

That's important because it enables you to make a copy of a file to the same directory as the original:

```
$ cp example.txt example.txt
cp: 'example.txt' and 'example.txt' are the same file.
$ cp example.txt example_copy.txt
```

To copy a directory, you must use the ``-r`` option, which stands for ``--recursive``.
This option runs ``cp`` on the directory inode, and then on all files within the directory.
Without the ``-r`` option, ``cp`` doesn't even recognize a directory as an object that can be copied:

```
$ cp notes/ notes-backup
cp: -r not specified; omitting directory 'notes/'
$ cp -r notes/ notes-backup
```


## Cat

The ``cat`` command is one of the most misunderstood commands, but only because it happens to fit nicely into the extreme flexibility characteristic of a [POSIX](https://opensource.com/article/19/7/what-posix-richard-stallman-explains) system.
Among everything else it does (including its intended purpose of con*cat*enating files), it can also copy.

For instance, with ``cat`` you can  [create two copies from one file](https://opensource.com/article/19/2/getting-started-cat-command) with just one command.
You can't do that with ``cp``.

A significance of ``cat`` being used to copy a file is how the system interprets the action.
When you use ``cp`` to copy a file, the file attributes are copied along with the file itself.
That means that the file permissions of the duplicate is the same as the original:

```
$ ls -l -G -g
-rw-r--r--. 1 57368 Jul 25 23:57  foo.jpg
$ cp foo.jpg bar.jpg
-rw-r--r--. 1 57368 Jul 29 13:37  bar.jpg
-rw-r--r--. 1 57368 Jul 25 23:57  foo.jpg
```

Using ``cat`` to read the contents of a file into another file, however, invokes a system call for the system to create a new file.
New files are subject to your default umask settings.
Run  ``umask -S`` to get the current setting:

```
$ umask
0002
```

This setting means that new files created in this location are granted 664 permission (because nothing is masked by the first digits of the umask setting, and only the **write** permission is blocked by the final digit).
To learn more about ``umask``, read Alex Juarez's article covering [umask](https://opensource.com/article/19/7/linux-permissions-101) and permissions in general.

When you copy with ``cat``, you don't actually copy the file.
You use cat to read the contents of the file, and then redirect the output into a new file:

```
$ cat foo.jpg > baz.jpg
$ ls -l -G -g
-rw-r--r--. 1 57368 Jul 29 13:37  bar.jpg
-rw-rw-r--. 1 57368 Jul 29 13:42  baz.jpg
-rw-r--r--. 1 57368 Jul 25 23:57  foo.jpg
```

A brand new file was created with the system's default umask applied.

When all you want to do is copy a file, the technicalities usually don't matter.
But sometimes you do want to copy a file with specific permissions, and with ``cat`` you can do it all in one command.


## Rsync

The ``rsync`` command is a versatile tool for copying files, with the notable ability to synchronize your source and destination.
At its most simple, it can be used nearly the same as the ``cp`` command:

```
$ rsync example.txt example_copy.txt
$ ls
example.txt    example_copy.txt
```

The command's true power lies in its ability to *not* copy when it's not necessary.
If you use ``rsync`` to copy a file into a directory, but that file already exists in that directory, then ``rsync`` doesn't bother performing the copy operation.
Locally, that doesn't necessarily mean much, but if you're copying gigabytes of data to a remote server, it make a world of difference.
What does make a difference even locally, though, is the command's ability to differentiate files that share the same name but which contain different data.
If you've ever found yourself faced with two copies of what is meant to be the same directory, then ``rsync`` can synchronize them into one directory containing the latest changes from each.
This is a pretty common occurrence in industries that haven't yet discovered the magic of version control, and for backup solutions in which there is one source of truth to propagate.

You can emulate this situation intentionally by creating two folders, one called ``example`` and the other ``example_dupe``.

```
$ mkdir example example_dupe
```

Then create a file in the first folder:

```
$ echo "one" > example/foo.txt
```

Use rsync to synchronize the two directories.
The most common options for this operation are ``-a`` (for *archive*, which ensures symlinks and other special files are preserved) and ``-v`` (for *verbose*, providing feedback to you on the progress of the command).

```
$ rsync -av example/ example_dupe/
```

The directories now contain the same information.

```
$ cat example/foo.txt
one
$ cat example_dupe/foo.txt
```

If the file you are treating as the source diverges, then the target is updated to match.

```
$ echo "two" >> example/foo.txt
$ rsync -av example/  example_dupe/
$ cat example_dupe/foo.txt
one
two
```

The ``rsync`` command is meant to copy data, not to act as a version control system.
For instance, if a file in the destination somehow gets ahead of a file in the source, that file is still overwritten because ``rsync`` compares files for divergence and assumes that the destination is always meant to mirror the source.

```
$ echo "You will never see this note again" > example_dupe/foo.txt
$ rsync -av example/  example_dupe/
$ cat example_dupe/foo.txt
one
two
```

If there is no change, then no copy occurs.

The ``rsync`` command has many options not available in ``cp``, such as the ability to set target permissions, exclude files, delete outdated files that don't appear in both directories, and much more.
It can be a powerful replacement for ``cp`` or just a useful supplement.


## Options

There are many ways to achieve essentially the same outcome on a POSIX system, so it seems that open source's reputation for flexibility is well earned.
Have I missed a useful way to copy data?
Share your copy hacks in the comments.