¿Por qué algunos comandos GNU Coreutils tienen la -T/--no-target-directory
opció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 -T
opción evita que la copia cree un dir/source
subdirectorio. Más bien /this/source
se identifica con dir
y los contenidos se asignan entre los árboles en consecuencia. Entonces, por ejemplo, /this/source/foo.c
va dir/foo.c
y sigue , en lugar de hacerlo dir/source/foo.c
.
Pero esto se puede lograr fácilmente sin la -T
opció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 dir
sí mismo, por lo que el efecto /this/path
se 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 -T
eso 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
?
.
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/file
existe y es un directorio, ¡obtienes el mismo diagnóstico! Pero ha demostrado lo-T
que 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..
truco del que estás hablando es agregar/.
a la fuente .El problema con
cp
/mv
/ln
como fueron diseñados originalmente es que son dos comandos en uno ( copiar y copiar en ).es copiar A a B o copiar A a B ( copiar A a B / A ) dependiendo de si
B
existe 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.
copia A a B independientemente. Si
B
existe y es un directorio, eso fallará (a menos que lo pase-r
). En cualquier caso, no terminará con unA
archivo dentroB
cuando pretendíaA
ser copiado a B.Y:
es la copia en .
fuente
cp A B
el comando, no hará lo que pretendía. Y hacerlo[ -e B ] || [ -L B ] || cp A B
todavía tiene una condición de carrera quecp -Tn A B
no tiene.El
-T
puede proporcionar un fracaso si existe un directorio de forma incorrecta para lo que debería ser un archivo de destino: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.
fuente
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.
fuente