Last time I wrote about using the --reference flag for quickly replicating various aspects of permissions in Linux. Today’s post is how to copy files and retain various attributes, like permissions, ownership, and SELinux context.

First, a little background on how permissions are set when copying.

How Permissions are Set When Moving Files

Or Why the Heck Do Permissions Change with Copying?!

So you’ve noticed that when using the mv command permissions will stay the same, but using cp changes then. What’s going on here?

Turns out this actually makes a lot of sense. In *nix, permissions are set based on the directory when a file is created. And since cp creates a new file from the original, it takes on the permissions of the folder it was created in.

So how can you avoid this? Use the -a flag, which will preserve the permissions, owner and SELinux context of the original (if your user has the permissions to do so). If you haven’t guessed already - this is the archive flag. You can also use just -p to just preserve Unix permissions, or --preserve to select the attributes you want to save.

Syntax

Just like normal for the cp command:

cp -a original_file destination_file

Or to use the --preserve flag just to retain ownership, try

cp --preserve=owner original_file destination_file

Example

In this example, we’ll start with a file, original that has 777 permissions, and copy both ways.

First we’ll look at the permissions for original with ls -lZ

-rw-r--r--. 1 apache apache unconfined_u:object_r:unlabeled_t:s0 0 Apr 15 15:14 original

Now we’ll do a normal copy.

cp original basic_copy

If we run ls -lZ, you’ll see the permissions are very different.

-rw-r--r--. 1 eugene eugene unconfined_u:object_r:user_tmp_t:s0  0 Apr 15 15:21 basic_copy
-rwxrwxrwx. 1 apache apache unconfined_u:object_r:unlabeled_t:s0 0 Apr 15 15:14 original

Now instead of doing a normal copy, we’ll use the -a flag to keep permissions.

cp -a original perms_retained

Now we’ll run ls -lZ again, and look at the results.

-rwxrwxrwx. 1 apache apache unconfined_u:object_r:unlabeled_t:s0 0 Apr 15 15:14 original
-rwxrwxrwx. 1 apache apache unconfined_u:object_r:unlabeled_t:s0 0 Apr 15 15:14 perms_retained

Sure enough, everything is the same for perms_retained!

Note: If your user lacks the right permissions to set owner, group, or SELinux context, then the defaults will be set instead. So if you’re dealing with system files, or files owned by another user, you’ll probably need to run this command as sudo.