cp --no-target-directory explicado

cp --no-target-directory explicado

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/sourcefoi renomeado para /tmp/dest: ele poderia ter sido renomeado para /tmp/dest/source, se algum outro processo fosse criado /tmp/destcomo um diretório. No entanto, se mv -T /tmp/source /tmp/destfor bem-sucedido, não há dúvida de que /tmp/source was renamed to/tmp/dest`. (fonte)

Responder1

Por padrão, cptesta se o seu último argumento é um diretório existente. Se isso acontecer, cpcria 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 cpcopia a fonte para wibble/bar. Se wibblenão existir, cpvincula 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 ). -TDessa forma, se cptiver sucesso, você pode ter certeza de que a cópia será chamada wibble. Se wibblejá existir como um diretório, cpfalhará.

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 mve 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 -Tcopie 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-directoryse 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/. bque copia o diretório de origema para be 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’

informação relacionada