Pourquoi certaines commandes GNU Coreutils ont-elles l' -T/--no-target-directory
option? Il semble que tout ce qu'il fait peut être réalisé en utilisant la sémantique de .
(self dot) dans une hiérarchie de répertoires Unix traditionnelle.
Considérant:
cp -rT /this/source dir
L' -T
option empêche la copie de créer un dir/source
sous - répertoire. Il /this/source
est plutôt identifié avec dir
et le contenu est cartographié entre les arbres en conséquence. Ainsi, par exemple, /this/source/foo.c
va à dir/foo.c
et ainsi de suite, plutôt qu'à dir/source/foo.c
.
Mais cela peut être facilement accompli sans l' -T
option en utilisant:
cp -r /this/source/. dir # Probably worked fine since dawn of Unix?
Sémantiquement, le composant de point de fin est copié en tant qu'enfant de dir
, mais bien sûr cet "enfant" existe déjà (donc n'a pas besoin d'être créé) et est en fait dir
lui-même, donc l'effet /this/path
est identifié avec dir
.
Cela fonctionne très bien si le répertoire courant est la cible:
cp -r /this/tree/node/. . # node's children go to current dir
Y at - il quelque chose que vous pouvez faire seulement avec -T
qui peut rationaliser son existence? (Outre la prise en charge des systèmes d'exploitation qui n'implémentent pas le répertoire dot, une justification non mentionnée dans la documentation.)
Le point ci-dessus ne résout-il pas les mêmes conditions de concurrence que celles mentionnées dans la documentation GNU Info -T
?
.
astuce fait le travail lors de la copie d' un fichier, mais pas lors du renommage son nom de base en même temps!cp /path/to/file /target/dir/.
S'il/target/dir/file
existe et qu'il s'agit d'un répertoire, vous obtenez le même diagnostic! Mais vous avez montré ce-T
que cela ne peut pas être fait sans lui en une seule étape, sans conditions de concurrence: copiez un fichier et changez son nom sans qu'il soit shunté dans un sous-répertoire..
astuce dont vous parlez consiste à ajouter/.
à la source .Le problème avec
cp
/mv
/ln
comme ils ont été initialement conçus est qu'ils sont deux commandes en une ( copier vers et copier dans ).est soit copier A vers B ou copier A dans B ( copier A vers B / A ) selon qu'il
B
existe et est un répertoire ou non (et plus de variantes si B est un lien symbolique vers un répertoire).C'est mauvais parce que c'est ambigu. Les implémentations GNU ont donc ajouté des options pour contourner cela.
copie A à B de toute façon . S'il
B
existe et est un répertoire, cela échouera (sauf si vous passez-r
). Dans tous les cas, vous ne vous retrouverez pas avec unA
fichier à l'intérieurB
lorsque vous souhaitiezA
être copié sur B.Et:
est la copie en .
la source
cp A B
la commande ne fera pas ce que vous vouliez. Et faire a[ -e B ] || [ -L B ] || cp A B
toujours une condition de course quicp -Tn A B
n'a pas.Le
-T
peut fournir un échec si un répertoire n'existe pas correctement pour ce qui devrait être un fichier de destination:Autrement dit, au lieu de réussir en cas de copie inattendue dans un sous-répertoire, un avertissement et un état de sortie non satisfaisant se produisent, ce qui pourrait entraîner l'arrêt du script et inspecter par l'homme pourquoi il existe un répertoire où il ne devrait pas être une.
la source
L'utilisation d'un indicateur est également beaucoup plus claire et présente moins de risques d'effets indésirables lorsque la commande est utilisée dans un script au lieu d'être entrée manuellement. Corriger des points sur des chemins dans un script peut se traduire par toutes sortes de méfaits inattendus.
la source