Qual é o valor agregado da opção -T no GNU cp e mv?

24

Por que alguns comandos GNU Coreutils têm a opção -T/--no-target-directory ? Parece que tudo o que ele faz pode ser alcançado usando a semântica do . (auto ponto) em uma hierarquia de diretório Unix tradicional.

Considerando:

cp -rT /this/source dir

A opção -T impede que a cópia crie um subdiretório dir/source . Em vez disso, /this/source é identificado com dir e o conteúdo é mapeado entre as árvores de acordo. Portanto, por exemplo, /this/source/foo.c vai para dir/foo.c e assim por diante, em vez de para dir/source/foo.c .

Mas isso pode ser facilmente realizado sem a opção -T usando:

cp -r /this/source/. dir  # Probably worked fine since dawn of Unix?

Semanticamente, o componente de ponto final é copiado como um filho de dir , mas é claro que "filho" já existe (então não precisa ser criado) e é realmente dir , então o efeito é que /this/path é identificado com dir .

Funciona bem se o diretório atual for o destino:

cp -r /this/tree/node/. . # node's children go to current dir

Existe algo que você pode fazer somente com -T que possa racionalizar sua existência? (Além do suporte a sistemas operacionais que não implementam o diretório dot, uma justificativa não mencionada na documentação.)

O truque de pontos acima não resolve as mesmas condições de corrida mencionadas na documentação do GNU Info sobre -T ?

    
por Kaz 09.06.2016 / 21:04

4 respostas

27

Seu truque . só pode ser usado quando você copia um diretório, não um arquivo. A opção -T funciona com diretórios e arquivos. Se você fizer:

cp srcfile destfile

e já existe um diretório chamado destfile que copia para destfile/srcfile , o que pode não ser o objetivo. Então você usa

cp -T srcfile destfile

e você recebe corretamente o erro:

cp: cannot overwrite directory 'destfile' with non-directory

Se você tentou usar o método . , a cópia nunca funcionaria:

cp: cannot stat 'srcfile/.': Not a directory
    
por 09.06.2016 / 21:40
19

O problema com cp / mv / ln como eles foram originalmente projetados é que eles são dois comandos em um ( copiar para e copiar em ).

cp A B

é copiar A para B ou copiar A em B ( copiar A para B / A ) dependendo se o B existe e é um diretório ou não (e mais variações se B for um symlink para um diretório).

Isso é ruim porque é ambíguo. Então as implementações GNU adicionaram opções para contornar isso.

cp -T A B

copia A para B independentemente. Se B existir e for um diretório, isso falhará (a menos que você passe -r ). Em qualquer caso, você não vai acabar com um arquivo A dentro de B quando você pretende que A seja copiado para B.

E:

cp -t B A

é a cópia para .

    
por 09.06.2016 / 22:54
6

O -T pode fornecer uma falha se um diretório existir incorretamente para o que deveria ser um arquivo de destino:

$ mkdir mustbeafile
$ touch afile
$ cp -T afile mustbeafile
cp: cannot overwrite directory 'mustbeafile' with non-directory
$ echo $?
1
$ cp afile mustbeafile
$ 

Ou seja, em vez de sucesso-no-inesperado-copiar-para-um-subdiretório, ocorre um aviso e um status de saída não bom, o que poderia fazer com que um script seja abortado e o humano inspecione por que há um diretório onde não deveria ser um.

    
por 09.06.2016 / 21:11
0

O uso de um sinalizador também é muito mais claro e tem menos risco de efeitos não intencionais, quando o comando é usado em um script, em vez de ser inserido manualmente. Colocar pontos em caminhos em um script pode acabar em todos os tipos de danos inesperados.

    
por 10.06.2016 / 11:24

Tags