Por que 'cp -a. / dir 'copia o conteúdo em vez do diretório?

3

Eu queria copiar um diretório no qual eu estava no momento. Experimentei cp -a . ~/xyz

Copiou o conteúdo do diretório, mas isso funcionou: cp -a "$(pwd)" ~/xyz
[Como desejado, este copiou o diretório envolvendo o conteúdo também.]

Dot parecia estar fazendo o que o Splat faria ... Por que o . não funciona?

    
por dvdrtrgn 07.08.2014 / 19:20

1 resposta

5

Ele fez isso porque . não é um nome que pode ser usado para criar um subdiretório.

cp -a . ~/xyz cópias ./file1 a ~/xyz/./file1 , ./file2 a ~/xyz/./file2 , etc. Mas ~/xyz/./file1 e ~/xyz/file1 são iguais, então o efeito é copiar o conteúdo do diretório atual para ~/xyz .

Você pode ver isso se adicionar a opção --verbose a cp para exibir cada nome de caminho conforme é copiado:

$ cp -av . ../foo/
‘./file1’ -> ‘../foo/./file1’
‘./file2’ -> ‘../foo/./file2’

Uma diferença notável entre . e * aqui é que cp -a . /dir copiará os arquivos ocultos, ao contrário de * (que não corresponde aos arquivos ocultos).

~ e * são metacaracteres de shell, o que significa que eles são expandidos pelo shell antes de cp vê-los. Por outro lado, . é uma entrada de diretório comum (que por acaso aponta para o diretório que a contém). Seria possível que cp contivesse código que detecta quando . é a fonte de uma cópia recursiva e substitui o nome do diretório, mas isso não acontece, provavelmente porque ninguém achou importante.

Além disso, que nome deve usar? Isso é mais simples para diretórios do que arquivos, porque geralmente os sistemas de arquivos não permitem vários links físicos para um diretório (exceto as entradas . e .. ). Mas isso não considera links simbólicos. Os shells modernos geralmente rastreiam quando você digita um diretório por meio de um link simbólico e reflete isso em pwd .

    
por 07.08.2014 / 20:15