cp --no-target-directory explicado

8

Pergunta: eu preciso de um exemplo simples de como usar cp --no-target-directory .

Eu tenho algumas dificuldades em entender cp --no-target-directory . Eu entendo a explicação para mv --no-target-directory , mas posso ' t realmente imaginar uma maneira de usá-lo para cp .

For example, when the command mv /tmp/source /tmp/dest succeeds, there is no guarantee that /tmp/source was renamed to /tmp/dest: it could have been renamed to /tmp/dest/source instead, if some other process created /tmp/dest as a directory. However, ifmv -T /tmp/source /tmp/dest succeeds, there is no question that /tmp/source was renamed to/tmp/dest'. (source)

    
por erch 13.10.2013 / 05:01

3 respostas

12

Por padrão, cp testa se seu último argumento é um diretório existente. Se isso acontecer, cp criará um link dentro desse diretório, com o nome base da origem. Isto é, dado o comando

cp foo/bar wibble

se wibble for um diretório existente, então cp copia a origem para wibble/bar . Se wibble não existir, então cp ligará a fonte a wibble .

Se você quiser ter certeza de que a cópia é sempre wibble , você pode especificar a opção --no-target-directory (alias -T ). Dessa forma, se cp for bem-sucedida, você pode ter certeza de que a cópia é chamada wibble . Se wibble já existia como um diretório, então cp falhará.

Em forma de tabela:

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 retornará um erro. Isso é útil quando você espera que o diretório não exista: você recebe uma mensagem de erro em vez de algo imprevisível acontecendo.

O mesmo se aplica a mv e ln . Se o destino for um diretório existente, com -T , eles sinalizarão um erro em vez de fazer algo diferente em silêncio.

Com cp , há um caso diferente. Se você fizer uma cópia recursiva e a origem for um diretório, então cp -T copia o conteúdo da origem no destino, em vez de copiar a própria fonte. 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'
    
por 17.01.2014 / 02:03
8

Você usaria --no-target-directory se não quiser uma fonte diretório copiado abaixo de um diretório de destino existente, você deseja que o diretório de origem seja copiado para o diretório de destino.

Aqui está um exemplo de uma 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 conseguir algo do mesmo efeito sufixando a origem nome (s) de diretório com barra de corte /. como em: cp -r a/. b quais cópias diretório de origem a para b e não abaixo b .

Nenhum dos métodos acima é o mesmo que dizer "copiar apenas o conteúdo do diretório de origem para o destino existente "desde se você pedir para preservar tempo e permissões, o destino existente diretório irá 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 transfere o modo ou os registros de data e hora do diretório de origem para o diretório de destino.

    
por 13.10.2013 / 06:46
2

Como sobre 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 de Dir_1 que seriam perdidos por um simples 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’
    
por 13.10.2013 / 05:42