7
$ cp --no-preserve=mode --parents /sys/power/state /tmp/test/
$ cp --no-preserve=mode --parents /sys/bus/cpu/drivers_autoprobe /tmp/test/

The second of the two lines will fail with

cp: cannot make directory ‘/tmp/test/sys/bus’: Permission denied

And the reason is that /tmp/test/sys is created without write permission (as is the original /sys); a normal mkdir /tmp/test/sys2 would not have done this:

$ ls -la /tmp/test/
total 32
drwxr-xr-x  3 robert.siemer domain^users  4096 Oct 11 13:56 .
drwxrwxrwt 13 root          root         20480 Oct 11 13:56 ..
dr-xr-xr-x  3 robert.siemer domain^users  4096 Oct 11 13:56 sys
drwxr-xr-x  2 robert.siemer domain^users  4096 Oct 11 13:59 sys2

How can I instruct cp to not preserve the mode, apart from --no-preserve=mode, which does not work as I believe it should...?

Or which tool should I use to copy a list of files without preserving “anything” except symlinks?

2 Answers2

15

In case you are using GNU coreutils. This is a bug which is fixed in version 8.26.

https://lists.gnu.org/archive/html/bug-coreutils/2016-08/msg00016.html

So the alternative tool would be an up-to-date coreutils, or for example rsync which is able to do that even with preserving permissions:

$ rsync -a --relative  /sys/power/state /tmp/test
$ rsync -a --relative  /sys/bus/cpu/drivers_autoprobe /tmp/test/

Though I see rsync has other problems for this particular sysfs files, see rsync option to disable verification?

Another harsh workaround would be to chmod all the dirs after each cp command.

$ find /tmp/test -type d -exec chmod $(umask -S) {} \;

(The find/chmod command above would also not work for any combination of existing permissions and umask.)

BTW you could report this bug to your Linux-Distribution and they might fix your 8.21 package via maintenance updates.

rudimeier
  • 10,315
-1

A simple workaround for the bug

#!/bin/sh

for last; do : ; done

while [ $# -gt 1 ]; do
  mkdir -p "${last}/$(dirname "$1")"
  cp --parents "$1" "$last"
  shift
done
yarl
  • 502