¿Cuál es el valor agregado de la opción -T en GNU cp y mv?

26

¿Por qué algunos comandos GNU Coreutils tienen la -T/--no-target-directoryopción? Parece que todo lo que hace se puede lograr utilizando la semántica del .(punto propio) en una jerarquía de directorios Unix tradicional.

Considerando:

cp -rT /this/source dir

La -Topción evita que la copia cree un dir/sourcesubdirectorio. Más bien /this/sourcese identifica con diry los contenidos se asignan entre los árboles en consecuencia. Entonces, por ejemplo, /this/source/foo.cva dir/foo.cy sigue , en lugar de hacerlo dir/source/foo.c.

Pero esto se puede lograr fácilmente sin la -Topción de usar:

cp -r /this/source/. dir  # Probably worked fine since dawn of Unix?

Semánticamente, el componente de punto final se copia como un elemento secundario de dir, pero, por supuesto, ese "elemento secundario" ya existe (por lo que no tiene que ser creado) y es en dirsí mismo, por lo que el efecto /this/pathse identifica con él dir.

Funciona bien si el directorio actual es el objetivo:

cp -r /this/tree/node/. . # node's children go to current dir

¿Hay algo que solo puedas hacer con -Teso que pueda racionalizar su existencia? (Además del soporte para sistemas operativos que no implementan el directorio de puntos, una razón no mencionada en la documentación).

¿El truco de puntos anterior no resuelve las mismas condiciones de carrera que se mencionan en la documentación de GNU Info -T?

Kaz
fuente

Respuestas:

29

Su .truco solo puede usarse cuando está copiando un directorio, no un archivo. La -Topción funciona con directorios y archivos. Si lo haces:

cp srcfile destfile

y ya hay un directorio con el nombre al destfileque se copiará destfile/srcfile, que puede no ser el previsto. Entonces usas

cp -T srcfile destfile

y obtienes el error correctamente:

cp: cannot overwrite directory `destfile' with non-directory

Si intentara usar el .método, la copia nunca funcionaría:

cp: cannot stat `srcfile/.`: Not a directory
Barmar
fuente
El .truco que hace el trabajo al copiar un archivo, pero no al cambiar el nombre de su nombre base al mismo tiempo! cp /path/to/file /target/dir/. Si /target/dir/fileexiste y es un directorio, ¡obtienes el mismo diagnóstico! Pero ha demostrado lo -Tque no se puede hacer sin él en un solo paso, sin condiciones de carrera: copie un archivo y cambie su nombre sin que se desvíe a un subdirectorio.
Kaz
3
Eso no es lo mismo: el .truco del que estás hablando es agregar /.a la fuente .
Barmar
21

El problema con cp/ mv/ lncomo fueron diseñados originalmente es que son dos comandos en uno ( copiar y copiar en ).

cp A B

es copiar A a B o copiar A a B ( copiar A a B / A ) dependiendo de si Bexiste y es un directorio o no (y más variaciones si B es un enlace simbólico a un directorio).

Eso es malo porque es ambiguo. Entonces, las implementaciones de GNU han agregado opciones para evitar eso.

cp -T A B

copia A a B independientemente. Si Bexiste y es un directorio, eso fallará (a menos que lo pase -r). En cualquier caso, no terminará con un Aarchivo dentro Bcuando pretendía Aser copiado a B.

Y:

cp -t B A

es la copia en .

Stéphane Chazelas
fuente
La filosofía original de Unix es asumir que sabes lo que haces y felizmente te permitirá dispararte en el pie.
Lenne
44
@Lenne, pero aquí no te da una manera de evitar dispararte en el pie. Si alguien crea un directorio B o un enlace simbólico a algún directorio justo antes de ejecutar cp A Bel comando, no hará lo que pretendía. Y hacerlo [ -e B ] || [ -L B ] || cp A Btodavía tiene una condición de carrera que cp -Tn A Bno tiene.
Stéphane Chazelas
6

El -Tpuede proporcionar un fracaso si existe un directorio de forma incorrecta para lo que debería ser un archivo de destino:

$ mkdir mustbeafile
$ touch afile
$ cp -T afile mustbeafile
cp: cannot overwrite directory `mustbeafile' with non-directory
$ echo $?
1
$ cp afile mustbeafile
$ 

Es decir, en lugar de éxito en copia inesperada a subdirectorio, se produce una advertencia y un estado de salida incorrecto, lo que podría provocar que un script se cancele, y el humano inspeccione por qué hay un directorio donde no debería ser uno.

thrig
fuente
0

El uso de un indicador también es mucho más claro y tiene menos riesgo de efectos no deseados, cuando el comando se usa en un script en lugar de ingresarse manualmente. Parchear puntos en los caminos en un script podría terminar en todo tipo de travesuras inesperadas.

rackandboneman
fuente