35

How do you use the cp command without changing the target file's permissions? For example:

cp /tmp/file   /home/file

I don't want to change chown and chgrp on /home/file.

Tom Hale
  • 1,005
  • 1
  • 12
  • 23
David
  • 423
  • 2
  • 6
  • 12
  • 3
    It's not clear whether you are asking about preserving the source permissions or the target permissions. You've also cross-site spammed to SuperUser. – Tom Shaw May 26 '11 at 09:00
  • For the record, the "preservation" options are in reference to the **source**. `cp -p` makes the target attributes match (thereby preserving) the source attributes. – mpersico Apr 20 '17 at 16:54
  • 3
    I just stumbled upon this page. cp by default ought to preserve the target files permissions and user:group because it opens the target in update mode and retaining its inode. So it's not clear to my why the answers don't indicate this. – dozer Apr 21 '17 at 11:58
  • 1
    This question is moot. GNU `cp` default behaviour is as desired by this question, as [demonstrated here](https://serverfault.com/a/1048378/322507). – Tom Hale Jan 03 '21 at 09:59

6 Answers6

38

If you've only opened the manual for cp...

The next will not overwrite the file permissions and ownership + groupship:

cp --no-preserve=mode,ownership /tmp/file /home/file

Note that root privileges are needed if you want to preserve the ownership and groupship.

An excerpt from the manual:

  --preserve[=ATTR_LIST]
      preserve   the   specified   attributes   (default:  mode,owner-
      ship,timestamps), if possible  additional  attributes:  context,
      links, xattr, all
Lekensteyn
  • 6,111
  • 6
  • 37
  • 55
  • 2
    Not exactly what the author wanted. `--no-preserve` makes sense if used after `--preserve` (or its aliases), otherwise it doesn't affect the behavior of `cp`. The author wanted to keep the file mode of an existing target file and only overwrite its contents – basin Oct 02 '18 at 09:15
  • Ex: replace ssh host keys `cp --no-preserve=mode,ownership ssh* /etc/ssh/`. This makes the secret keys world-readable. – basin Oct 02 '18 at 09:20
  • 1
    The man page's --preserve explanation is IMHO nonsensical as it does not make it clear preserve what: The source or target attributes – Waslap Feb 22 '19 at 12:40
  • `--no-preserve=all` is default. And by default [GNU `cp` doesn't update target permissions anyway](https://serverfault.com/a/1048378/322507). – Tom Hale Jan 03 '21 at 10:05
13

cat will work, too:

cat /tmp/file > /home/file
Cakemox
  • 24,141
  • 6
  • 41
  • 67
4

By default, GNU cp (version 8.32) will NOT overwrite destination permissions, so the question is moot:

% ls -li
total 8,192
19392015 -rwxrwxrwx 1 ravi ravi 4 Jan  3 16:54 bar*
19392014 -rw-r--r-- 1 ravi ravi 4 Jan  3 16:46 foo
% cp foo bar
% ls -li
total 8,192
19392015 -rwxrwxrwx 1 ravi ravi 4 Jan  3 16:57 bar*
19392014 -rw-r--r-- 1 ravi ravi 4 Jan  3 16:46 foo
%

In the case where the destination file is not writable (even though the directory is), cp will say:

cp: cannot create regular file 'dest-file': Permission denied

Other options besides cp:

cat will preserve the inode and permissions of the destination file:

cat file-with-new-data > file-to-overwrite

However, redirections won't work with sudo.

If you want to sudo and keep the destination permissions, use this:

< file-with-new-data sudo tee file-to-overwrite > /dev/null

This is equivalent to the more verbose:

cat file-with-new-data | sudo tee file-to-overwrite > /dev/null
Tom Hale
  • 1,005
  • 1
  • 12
  • 23
-1

Or you can use even better install program from GNU coreutils that has been made for this particular purpose. Please note it is not able to recurse (no -R or -r option).

http://www.gnu.org/software/coreutils/manual/html_node/install-invocation.html

lzap
  • 2,704
  • 2
  • 22
  • 22
  • 1
    I didn't see a switch for this to preserve the target's ower or group. Just force it to a new value. – Pete Oct 07 '15 at 22:06
-1

Don't use permission-related switches at all, especially --no-preserve, because it behaves strangely:

good:

[il@localhost Downloads]$ sudo cp ssh_host_* /etc/ssh/
[il@localhost Downloads]$ ls -l /etc/ssh
total 604
-rw-r--r--  1 root root     581843 Oct 20  2017 moduli
-rw-r--r--  1 root root       2276 Oct 20  2017 ssh_config
-rw-------  1 root root       3907 Oct 20  2017 sshd_config
-rw-r-----. 1 root ssh_keys    227 Oct  2 12:26 ssh_host_ecdsa_key
-rw-r--r--. 1 root root        172 Oct  2 12:26 ssh_host_ecdsa_key.pub
-rw-r-----. 1 root ssh_keys    411 Oct  2 12:26 ssh_host_ed25519_key
-rw-r--r--. 1 root root        100 Oct  2 12:26 ssh_host_ed25519_key.pub
-rw-r-----. 1 root ssh_keys   1679 Oct  2 12:26 ssh_host_rsa_key
-rw-r--r--. 1 root root        392 Oct  2 12:26 ssh_host_rsa_key.pub

bad:

[il@localhost Downloads]$ sudo cp --no-preserve=mode,ownership ssh_host_* /etc/ssh/
[il@localhost Downloads]$ ls -l /etc/ssh
total 604
-rw-r--r--  1 root root     581843 Oct 20  2017 moduli
-rw-r--r--  1 root root       2276 Oct 20  2017 ssh_config
-rw-------  1 root root       3907 Oct 20  2017 sshd_config
-rw-r--r--. 1 root ssh_keys    227 Oct  2 12:27 ssh_host_ecdsa_key
-rw-r--r--. 1 root root        172 Oct  2 12:27 ssh_host_ecdsa_key.pub
-rw-r--r--. 1 root ssh_keys    411 Oct  2 12:27 ssh_host_ed25519_key
-rw-r--r--. 1 root root        100 Oct  2 12:27 ssh_host_ed25519_key.pub
-rw-r--r--. 1 root ssh_keys   1679 Oct  2 12:27 ssh_host_rsa_key
-rw-r--r--. 1 root root        392 Oct  2 12:27 ssh_host_rsa_key.pub
basin
  • 548
  • 1
  • 3
  • 20
-1

The cp doesn't override permissions by default. If you want to make sure permission won't be overridden, use

cp --preserve=mode,ownership /tmp/file /target_dir_where_file_resides
rok
  • 149
  • 8
  • 1
    That actually forces overwriting of the target permissions -- it preserves the permissions of the source file. – Tom Hale Jan 03 '21 at 09:44