Warum haben einige GNU Coreutils-Befehle die -T/--no-target-directory
Option? Es scheint, dass alles, was es tut, mit der Semantik von .
(self dot) in einer traditionellen Unix-Verzeichnishierarchie erreicht werden kann.
In Anbetracht:
cp -rT /this/source dir
Die -T
Option verhindert, dass die Kopie ein dir/source
Unterverzeichnis erstellt. Vielmehr /this/source
wird mit identifiziert dir
und der Inhalt entsprechend zwischen den Bäumen abgebildet. So /this/source/foo.c
geht zum Beispiel zu dir/foo.c
und so weiter, anstatt zu dir/source/foo.c
.
Dies kann jedoch problemlos ohne die folgende -T
Option erreicht werden:
cp -r /this/source/. dir # Probably worked fine since dawn of Unix?
Semantisch wird die abschließende Punktkomponente als Kind von kopiert dir
, aber natürlich existiert dieses "Kind" bereits (muss also nicht erstellt werden) und ist tatsächlich dir
selbst, so dass der Effekt derjenige /this/path
ist, mit dem identifiziert wird dir
.
Es funktioniert einwandfrei, wenn das aktuelle Verzeichnis das Ziel ist:
cp -r /this/tree/node/. . # node's children go to current dir
Gibt es etwas , können Sie tun , nur mit , -T
dass seine Existenz rationalisieren? (Neben der Unterstützung für Betriebssysteme, die das Punktverzeichnis nicht implementieren, eine Begründung, die in der Dokumentation nicht erwähnt wird.)
Löst der obige Punkttrick nicht die gleichen Wettkampfbedingungen, die in der GNU Info-Dokumentation zu erwähnt sind -T
?
.
Trick funktioniert beim Kopieren einer Datei, nur nicht beim gleichzeitigen Umbenennen des Basisnamens!cp /path/to/file /target/dir/.
Wenn/target/dir/file
vorhanden und ein Verzeichnis ist, erhalten Sie die gleiche Diagnose! Aber Sie haben gezeigt, was-T
das nicht kann, ohne es in einem Schritt und ohne Race-Bedingungen zu tun: Kopieren Sie eine Datei und ändern Sie ihren Namen, ohne dass sie in ein Unterverzeichnis verschoben wird..
Trick, über den Sie sprechen, hängt/.
an die Quelle an .Das Problem mit
cp
/mv
/ln
wie sie ursprünglich entworfen wurden , ist , dass sie zwei Befehle in einer ( Kopie an und kopieren Sie in ).ist entweder Kopieren von A nach B oder Kopieren von A nach B ( Kopieren von A nach B / A ), je nachdem, ob
B
es ein Verzeichnis gibt oder nicht (und weitere Variationen, wenn B ein Symlink zu einem Verzeichnis ist).Das ist schlecht, weil es mehrdeutig ist. Daher haben die GNU-Implementierungen Optionen hinzugefügt, um dies zu umgehen.
Kopien von A bis B unabhängig. Wenn
B
vorhanden und ein Verzeichnis ist, schlägt dies fehl (es sei denn, Sie übergeben-r
). In jedem Fall erhalten Sie keineA
Datei,B
wenn Sie beabsichtigenA
, nach B kopiert zu werden .Und:
ist die Kopie in .
quelle
cp A B
den Befehl ausführen, wird nicht das getan, was Sie beabsichtigt haben. Und dabei ist[ -e B ] || [ -L B ] || cp A B
immer noch eine Racebedingung, diecp -Tn A B
es nicht gibt.Dies
-T
kann zu einem Fehler führen, wenn ein Verzeichnis für eine Zieldatei nicht ordnungsgemäß vorhanden ist:Dies bedeutet, dass anstelle von Erfolg beim unerwarteten Kopieren in ein Unterverzeichnis eine Warnung und ein nicht einwandfreier Beendigungsstatus angezeigt werden, die zum Abbruch eines Skripts führen können eins sein.
quelle
Die Verwendung eines Flags ist auch viel klarer und birgt ein geringeres Risiko für unbeabsichtigte Auswirkungen, wenn der Befehl in einem Skript verwendet wird, anstatt manuell eingegeben zu werden. Das Patchen von Punkten auf Pfade in einem Skript kann zu unerwartetem Unheil führen.
quelle