
Pergunta:Preciso de um exemplo simples de como usar o cp --no-target-directory
.
Sinto algumas dificuldades de compreensão cp --no-target-directory
. eu entendoa explicação paramv --no-target-directory
, mas não consigo imaginar uma maneira de usá-lo para cp
.
Por exemplo, quando o comando
mv /tmp/source /tmp/dest
é bem-sucedido, não há garantia de que/tmp/source
foi renomeado para/tmp/dest
: ele poderia ter sido renomeado para/tmp/dest/source
, se algum outro processo fosse criado/tmp/dest
como um diretório. No entanto, semv -T /tmp/source /tmp/dest
for bem-sucedido, não há dúvida de que/tmp/source was renamed to
/tmp/dest`. (fonte)
Responder1
Por padrão, cp
testa se o seu último argumento é um diretório existente. Se isso acontecer, cp
cria um link dentro desse diretório, com o nome base da fonte. Ou seja, dado o comando
cp foo/bar wibble
if wibble
é um diretório existente e cp
copia a fonte para wibble/bar
. Se wibble
não existir, cp
vincula a fonte a wibble
.
Se quiser ter certeza de que a cópia será sempre wibble
, você poderá especificar a opção --no-target-directory
(alias ). -T
Dessa forma, se cp
tiver sucesso, você pode ter certeza de que a cópia será chamada wibble
. Se wibble
já existir como um diretório, cp
falhará.
Em forma tabular:
The target is … Without -T With -T
existing directory copy in the directory error
existing file (not dir) overwrite overwrite
does not exist create create
A única diferença é que com -T
, caso o destino seja um diretório existente, o comando retorna um erro. Isso é útil quando você espera que o diretório não exista: você recebe uma mensagem de erro em vez de algo imprevisto acontecer.
O mesmo se aplica a mv
e ln
. Se o destino for um diretório existente, com -T
, eles sinalizam um erro em vez de fazer algo diferente silenciosamente.
Com cp
, há um caso diferente. Se você fizer uma cópia recursiva e a origem for um diretório, cp -T
copie o conteúdo da origem para o destino, em vez de copiar a própria origem. Isto é, dado
$ tree source destination
source
└── foo
destination
└── bar
então
$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'
enquanto
% cp -rvT source destination
`source/foo' -> `destination/foo'
Responder2
Você usaria --no-target-directory
se não quiser que um diretório de origem seja copiadodebaixo deum diretório de destino existente, você deseja que o diretório de origem seja copiadoparao diretório de destino.
Aqui está um exemplo de cópia de diretório com e sem --no-target-directory
:
$ mkdir a
$ touch a/b a/c
$ find
.
./a
./a/c
./a/b
$ cp -r a b # b does not exist; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r a b # b already exists; a is copied *underneath* it
$ find
.
./b
./b/a
./b/a/b
./b/a/c
./a
./a/c
./a/b
$ rm -r b
$ mkdir b
$ cp -r --no-target-directory a b # b already exists; becomes copy of a
$ find
.
./b
./b/b
./b/c
./a
./a/c
./a/b
Você pode obter algo do mesmo efeito sufixando o(s) nome(s) do diretório de origem com barra-ponto /.
como em: cp -r a/. b
que copia o diretório de origema
para b
e nãodebaixo de b
.
Nenhum dos métodos acima é o mesmo que dizer "copiar apenas o conteúdo do diretório de origem para o destino existente", pois, se você solicitar a preservação do tempo e das permissões, o diretório de destino existente adquirirá o tempo e as permissões do diretório de origem. Um exemplo (editado para remover informações desnecessárias):
$ find . -ls
drwx------ Oct 13 13:31 ./b # note date and permissions
drwxr-xr-x Jan 1 2013 ./a # note date and permissions
-rw-r--r-- Oct 13 13:23 ./a/c
-rw-r--r-- Oct 13 13:23 ./a/b
$ cp -rp --no-target-directory a b # preserve mode and timestamps
$ find . -ls
drwxr-xr-x Jan 1 2013 ./b # note copied date and permissions
-rw-r--r-- Oct 13 13:23 ./b/b
-rw-r--r-- Oct 13 13:23 ./b/c
drwxr-xr-x Jan 1 2013 ./a
-rw-r--r-- Oct 13 13:23 ./a/c
-rw-r--r-- Oct 13 13:23 ./a/b
Uma cópia somente de conteúdo não transferiria o modo ou os carimbos de data/hora do diretório de origem para o diretório de destino.
Responder3
Que tal o seguinte?
$ cp -rvT Dir_1 Dir_2
‘Dir_1/File_3.txt’ -> ‘Dir_2/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/File_2.txt’
$ cp -rv Dir_1 Dir_2
‘Dir_1’ -> ‘Dir_2/Dir_1’
‘Dir_1/File_3.txt’ -> ‘Dir_2/Dir_1/File_3.txt’
‘Dir_1/File_1.txt’ -> ‘Dir_2/Dir_1/File_1.txt’
‘Dir_1/File_2.txt’ -> ‘Dir_2/Dir_1/File_2.txt’
Como tal, é apenas uma maneira diferente de escrever cp Dir_1/* Dir_2/
. No entanto, ele captura arquivos ocultos na raiz do Dir_1 que seriam perdidos por um simples arquivo cp *
.
$ touch Dir_1/.Hidden_File_{1,2,3}.txt
$ cp -rv Dir_1/* Dir_2
cp: No match.
$ cp -rvT Dir_1 Dir_2
‘Dir_1/.Hidden_File_2.txt’ -> ‘Dir_2/.Hidden_File_2.txt’
‘Dir_1/.Hidden_File_3.txt’ -> ‘Dir_2/.Hidden_File_3.txt’
‘Dir_1/.Hidden_File_1.txt’ -> ‘Dir_2/.Hidden_File_1.txt’