cp --no-target-directory erklärt

cp --no-target-directory erklärt

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

Ich habe einige Verständnisschwierigkeiten cp --no-target-directory. Ich verstehedie Erklärung fürmv --no-target-directory, aber ich kann mir nicht wirklich vorstellen, wofür man es verwenden könnte cp.

Wenn der Befehl beispielsweise mv /tmp/source /tmp/desterfolgreich ist, gibt es keine Garantie dafür, dass /tmp/sourceer in umbenannt wurde /tmp/dest: Er hätte /tmp/dest/sourcestattdessen in umbenannt werden können, wenn ein anderer Prozess /tmp/destein Verzeichnis erstellt hätte. Wenn er jedoch mv -T /tmp/source /tmp/desterfolgreich ist, besteht kein Zweifel daran, dass /tmp/source was renamed to/tmp/dest`. (Quelle)

Antwort1

Standardmäßig cpwird geprüft, ob das letzte Argument ein vorhandenes Verzeichnis ist. Wenn dies der Fall ist, cpwird ein Link innerhalb dieses Verzeichnisses mit dem Basisnamen der Quelle erstellt. Das heißt, bei dem Befehl

cp foo/bar wibble

Wenn wibblees sich um ein vorhandenes Verzeichnis handelt, cpwird die Quelle nach kopiert wibble/bar. Wenn wibblees nicht vorhanden ist, cpwird die Quelle mit verknüpft wibble.

Wenn Sie sicher sein möchten, dass die Kopie immer ist wibble, können Sie die Option --no-target-directory(Alias -T) angeben. Auf diese Weise cpkönnen Sie sicher sein, dass die Kopie bei Erfolg 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 -T, dass der Befehl einen Fehler zurückgibt, wenn das Ziel ein vorhandenes Verzeichnis ist. Dies ist nützlich, wenn Sie davon ausgehen, dass das Verzeichnis nicht existiert: Sie erhalten eine Fehlermeldung, anstatt dass etwas Unvorhergesehenes passiert.

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

Bei cpist der Fall anders. Wenn Sie eine rekursive Kopie durchführen und die Quelle ein Verzeichnis ist, dann cp -Tkopiert 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'

Antwort2

Sie verwenden --no-target-directory, wenn Sie nicht möchten, dass ein Quellverzeichnis kopiert wirddarunterein vorhandenes Zielverzeichnis, Sie möchten das Quellverzeichnis kopierenauf zudas 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 einen ähnlichen Effekt erzielen, indem Sie den Namen des Quellverzeichnisses mit einem Schrägstrich versehen, /.wie in: cp -r a/. bwhich copys source directorya auf zu bund nichtdarunter b.

Keine der oben genannten Methoden ist dasselbe wie „kopiere nur den Inhalt des Quellverzeichnisses in das vorhandene Ziel“, denn wenn du die Beibehaltung von Zeit und Berechtigungen angibst, erhält das vorhandene Zielverzeichnis die Zeit und Berechtigungen des Quellverzeichnisses. 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

Bei einer Nur-Inhalts-Kopie würden weder der Modus noch die Zeitstempel des Quellverzeichnisses in das Zielverzeichnis übertragen.

Antwort3

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’

An sich ist es nur eine andere Art, zu schreiben cp Dir_1/* Dir_2/. Es erkennt jedoch versteckte Dateien im Stammverzeichnis von Dir_1, die bei 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’

verwandte Informationen