cp --no-target-directory explicado

10

Pregunta: Necesito un ejemplo simple de cómo usar cp --no-target-directory.

Experimento algunas dificultades en la comprensión cp --no-target-directory. Entiendo la explicaciónmv --no-target-directory , pero realmente no puedo imaginar una forma de usarlo cp.

Por ejemplo, cuando el comando mv /tmp/source /tmp/desttiene éxito, no hay garantía de que /tmp/sourcese le haya cambiado el nombre /tmp/dest: podría haberle cambiado el nombre /tmp/dest/source, si algún otro proceso se hubiera creado /tmp/destcomo un directorio. Sin embargo, si mv -T /tmp/source /tmp/desttiene éxito, no hay duda de que /tmp/source was renamed to/ tmp / dest`. ( fuente )

erch
fuente

Respuestas:

15

Por defecto, cpprueba si su último argumento es un directorio existente. Si esto sucede, cpcrea un enlace dentro de ese directorio, con el nombre base de la fuente. Es decir, dado el comando

cp foo/bar wibble

si wibblees un directorio existente, cpcopia la fuente en wibble/bar. Si wibbleno existe, cpvincula la fuente a wibble.

Si desea asegurarse de que la copia sea siempre wibble, puede especificar la opción --no-target-directory(alias -T). De esa manera, si cptiene éxito, puede estar seguro de que se llama a la copia wibble. Si wibbleya existía como directorio, entonces cpfallará.

En 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

La única diferencia es que -T, en caso de que el destino sea un directorio existente, el comando devuelve un error. Esto es útil cuando espera que el directorio no exista: recibe un mensaje de error en lugar de que ocurra algo imprevisto.

Lo mismo se aplica a mvy ln. Si el objetivo es un directorio existente, con -T, señalan un error en lugar de hacer algo diferente en silencio.

Con cp, hay un caso diferente. Si realiza una copia recursiva y la fuente es un directorio, cp -Tcopia el contenido de la fuente en el destino, en lugar de copiar la fuente misma. Es decir, dado

$ tree source destination 
source
└── foo
destination
└── bar

entonces

$ cp -rv source destination
`source' -> `destination/source'
`source/foo' -> `destination/source/foo'

mientras

% cp -rvT source destination
`source/foo' -> `destination/foo'
Gilles 'SO- deja de ser malvado'
fuente
8

Lo usaría --no-target-directorysi no desea que se copie un directorio de origen debajo de un directorio de destino existente, desea que el directorio de origen se copie en el directorio de destino.

Aquí hay un ejemplo de una copia de directorio con y sin --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

Puede lograr algo del mismo efecto con el sufijo de los nombres del directorio de origen con punto y barra /.como en: cp -r a/. bque copia el directorio de origen a en b y no debajo b .

Ninguno de los métodos anteriores es lo mismo que decir "copiar solo el contenido del directorio de origen al destino existente" ya que, si solicita preservar el tiempo y los permisos, el directorio de destino existente adquirirá el tiempo y los permisos del directorio de origen. Un ejemplo (editado para eliminar información innecesaria):

$ 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

Una copia de solo contenido no transferiría el modo o las marcas de tiempo del directorio de origen al directorio de destino.

Ian D. Allen
fuente
2

¿Qué tal lo siguiente?

$ 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, es solo una forma diferente de escribir cp Dir_1/* Dir_2/. Sin embargo, captura archivos ocultos en la raíz de Dir_1 que se perderían con un simple 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’
Railgun2
fuente
funciona para mí con la --no-target-directoryopción [out] : siempre que use --recursive, todo está bien [con coreutils 8.12GNU / Linux]. La principal diferencia parece ser que con --no-target-directoryel contenido, pero no con el directorio en sí mismo, se copia [investigación aún en curso]
erch