Por que o modo cp --no-preserve = preserva o modo? Ferramentas alternativas disponíveis?

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

A segunda das duas linhas falhará com

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

E a razão é que /tmp/test/sys é criado sem permissão de gravação (como é o original /sys ); um normal mkdir /tmp/test/sys2 não teria feito isso:

$ 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

Como posso instruir cp para não preservar o modo, além de --no-preserve=mode , que não funciona como eu acredito que deveria ...?

Ou qual ferramenta devo usar para copiar uma lista de arquivos sem preservar "qualquer coisa", exceto links simbólicos?

    
por Robert Siemer 11.10.2016 / 14:05

2 respostas

14

No caso de você estar usando o GNU Coreutils. Este é um bug que foi corrigido na versão 8.26.

link

Portanto, a ferramenta alternativa seria um coreutils atualizado, ou, por exemplo, rsync , que é capaz de fazer isso mesmo com a preservação de permissões:

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

Embora eu veja que o rsync tem outros problemas para esses arquivos sysfs específicos, veja opção rsync para desabilitar a verificação?

Outra solução alternativa dura seria chmod todas as pastas após cada comando cp .

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

(O comando find / chmod acima também não funcionaria para qualquer combinação de permissões existentes e umask.)

BTW você pode relatar este bug para sua distribuição Linux e eles podem consertar seu pacote 8.21 através de atualizações de manutenção.

    
por 11.10.2016 / 14:17
-1

Uma solução simples para o bug

#!/bin/sh

for last; do : ; done

while [ $# -gt 1 ]; do
  mkdir -p "${last}/$(dirname "$1")"
  cp --parents "$1" "$last"
  shift
done
    
por 11.10.2016 / 14:55