cp --no-target-directory erklärt

10

Frage: Ich brauche ein einfaches Beispiel für die Verwendung cp --no-target-directory.

Ich habe einige Schwierigkeiten beim Verständnis cp --no-target-directory. Ich verstehe die Erklärung dafürmv --no-target-directory , kann mir aber nicht vorstellen, wie ich sie verwenden soll cp.

Wenn der Befehl beispielsweise mv /tmp/source /tmp/desterfolgreich ist, gibt es keine Garantie, /tmp/sourcein die umbenannt wurde /tmp/dest: Er hätte /tmp/dest/sourcestattdessen umbenannt werden können, wenn ein anderer Prozess /tmp/destals Verzeichnis erstellt worden wäre. Wenn dies jedoch mv -T /tmp/source /tmp/desterfolgreich ist, steht außer Frage, dass /tmp/source was renamed to/ tmp / dest`. ( Quelle )

erch
quelle

Antworten:

15

Standardmäßig wird cpgeprüft, ob das letzte Argument ein vorhandenes Verzeichnis ist. In diesem Fall cpwird in diesem Verzeichnis ein Link mit dem Basisnamen der Quelle erstellt. Das heißt, den Befehl gegeben

cp foo/bar wibble

Wenn wibblees sich um ein vorhandenes Verzeichnis handelt, wird cpdie Quelle in dieses Verzeichnis kopiert wibble/bar. Wenn wibblenicht vorhanden, wird cpdie Quelle mit verknüpft wibble.

Wenn Sie sicherstellen möchten, dass die Kopie immer vorhanden ist wibble, können Sie die Option --no-target-directory(Alias -T) angeben . Auf diese Weise können Sie bei cpErfolg sicher sein, dass die Kopie aufgerufen wird wibble. Wenn wibblebereits als Verzeichnis vorhanden, cpschlägt dies fehl.

In tabellarischer Form:

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

Der einzige Unterschied besteht darin, dass -Tder Befehl einen Fehler zurückgibt, falls das Ziel ein vorhandenes Verzeichnis ist. Dies ist nützlich, wenn Sie erwarten, dass das Verzeichnis nicht vorhanden ist: Sie erhalten eine Fehlermeldung, anstatt dass etwas Unvorhergesehenes passiert.

Gleiches gilt für mvund ln. Wenn das Ziel ein vorhandenes Verzeichnis ist -T, signalisieren sie einen Fehler, anstatt stillschweigend etwas anderes zu tun.

Bei cpgibt es einen anderen Fall. Wenn Sie eine rekursive Kopie erstellen und die Quelle ein Verzeichnis ist, cp -Tkopiert sie den Inhalt der Quelle in das Ziel, anstatt die Quelle selbst zu kopieren. Das heißt, gegeben

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

dann

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

wohingegen

% cp -rvT source destination
`source/foo' -> `destination/foo'
Gilles 'SO - hör auf böse zu sein'
quelle
8

Sie verwenden würden , --no-target-directorywenn Sie kopiert keine Quellverzeichnis wollen unter einem vorhandenen Zielverzeichnis, möchten Sie das Quellverzeichnis kopiert auf das Zielverzeichnis.

Hier ist ein Beispiel für eine Verzeichniskopie mit und ohne --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

Sie können den gleichen Effekt erzielen, indem Sie die Namen des Quellverzeichnisses mit einem Schrägstrich /.wie in: versehen, cp -r a/. bwodurch das Quellverzeichnis a auf b und nicht darunter kopiert wirdb .

Keine der oben genannten Methoden entspricht der Aussage "Kopieren Sie nur den Inhalt des Quellverzeichnisses in das vorhandene Ziel", da das vorhandene Zielverzeichnis die Zeit und die Berechtigungen des Quellverzeichnisses abruft, wenn Sie Zeit und Berechtigungen beibehalten möchten. Ein Beispiel (bearbeitet, um unnötige Informationen zu entfernen):

$ 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

Eine Nur-Inhalt-Kopie würde den Modus oder die Zeitstempel des Quellverzeichnisses nicht in das Zielverzeichnis übertragen.

Ian D. Allen
quelle
2

Wie wäre es mit folgendem?

$ 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’

Als solches ist es nur eine andere Art zu schreiben cp Dir_1/* Dir_2/. Es fängt jedoch versteckte Dateien im Stammverzeichnis von Dir_1 ab, die von einem einfachen übersehen würden 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
quelle
funktioniert bei mir mit der --no-target-directoryOption [out] : Solange ich --recursive verwende, ist alles in Ordnung [mit coreutils 8.12unter GNU / Linux]. Der Hauptunterschied scheint zu sein, dass mit --no-target-directorydem Inhalt, aber nicht dem Verzeichnis selbst kopiert wird [Forschung noch im Gange]
erch