Das dachte ich mir a
und es a/.
ist der gleiche Weg. Allerdings habe ich festgestellt, dasscpUndrsynckopiert den Verzeichnisinhalt statt des Verzeichnisses selbst, wenn /.
es zum Quellpfad hinzugefügt wird. Ich habe es auch versucht a/inner/..
; das hat auch funktioniert.
$ cp -r a b # Copies dir a into dir b.
$ cp -r a/. b # Copies files from dir a into dir b.
$ cp -r a/inner/.. b # Also copies files from dir a into dir b.
$ cd a && cp -r . ../b # One more way to copy inner files.
Ich verstehe, dass das nützlich ist. Aber ich bin etwas verwirrt, weil diese Funktion anscheinend Standards verletzt.
Wie funktioniert das? Ist diese Funktion irgendwo dokumentiert? Ist dies eine Funktion des Betriebssystems,cpoder bashen?
Antwort1
Ich verstehe, dass das nützlich ist. Aber ich bin etwas verwirrt, weil diese Funktion anscheinend Standards verletzt.
cpDas Verhalten beim rekursiven Kopieren von a/.
nach b
stimmt vollkommen mit seinem „normalen“ Verhalten überein.
Standardmäßig,cperstellt keine übergeordneten Verzeichnisse. Dies kann mit demElternschalten:
--parents
use full source file name under DIRECTORY
Aber was bedeutet das?
Das bedeutet, dass der Befehl
cp --parents -r some/path/to/source dest
kopiert den Inhalt des Quellverzeichnisses in dest/some/path/to/source
, der Befehl
cp -r some/path/to/source dest
kopiert den Inhalt des Quellverzeichnisses in dest/source
.
Ebenso der Befehl
cp -r some/path/to/source/. dest
kopiert den Inhalt des Quellverzeichnisses in dest/.
, was einfach ist dest
.
Dachte ich,
a
unda/.
es ist der gleiche Weg.
a
Unda/.
Istden gleichen Weg. Aber als Argument fürcp, es ist nur eine Zeichenfolge.
Beachten Sie, dass die Befehle
cp --parents -r some/path/to/source dest
Und
cd some/path/to && cp --parents -r source dest
wird sich auch anders verhalten.
Was ist mit
cp -r a/inner/.. b
? Sollte es unter Berücksichtigung Ihrer Erklärung nicht Dateien dorthin kopierenb/..
(also in das aktuelle Verzeichnis)?
Nun ja. Dies ist eine Ausnahme.
Zumindest in der GNU-Version voncp, es gibt einen Sonderfall für den ..
Basisnamen.
if (parents_option)
{
[removed]
}
else
{
char *arg_base;
/* Append the last component of 'arg' to 'target_directory'. */
ASSIGN_BASENAME_STRDUPA (arg_base, arg);
/* For 'cp -R source/.. dest', don't copy into 'dest/..'. */
dst_name = (STREQ (arg_base, "..")
? xstrdup (target_directory)
: file_name_concat (target_directory, arg_base,
NULL));
}
Die Motivation scheint darin zu liegen, das Kopieren außerhalb des Zielordners zu vermeiden, was – obwohl es vollkommen im Einklang mitcpDas Verhalten von in allen anderen Fällen – ist ein wenig kontraintuitiv und könnte unangenehme Folgen haben.
Schließlich glaube ich nicht, dass irgendjemand den Befehl erwarten würde
cp -r .. ~
um Dateien außerhalb seines Home-Verzeichnisses zu beeinflussen ...
Antwort2
$ mkdir a b a/inner
$ touch a/a{1..3} b/b{1..3}
$ ls -R
.:
a b
./a:
a1 a2 a3 inner
./a/inner:
./b:
b1 b2 b3
$ cp a b
cp: omitting directory ‘a’
$ cp a/. b
cp: omitting directory ‘a/.’
$ cp a/inner/.. b
cp: omitting directory ‘a/inner/..’
$ cd a && cp . ../b
cp: omitting directory ‘.’
$ cd ..
$ ls -R
.:
a b
./a:
a1 a2 a3 inner
./a/inner:
./b:
b1 b2 b3
Nichts von dem, was Sie sagen, passiert tatsächlich. Die vier cp
Befehle tun nichts. Vielleicht haben Sie einen Alias für „ cp
loaded“. Sie können dies mit überprüfen alias cp
.
Antwort3
Apropos rsync(1)
, lesen Sie das Handbuchsorgfältig. Es werden einige ungewöhnliche Konventionen verwendet, um „den Inhalt des Verzeichnisses“ gegenüber „das Verzeichnis und seinen Inhalt“ zu bezeichnen.
Für cp(1)
und andere Linux-Befehle, an derKernelEbene a
und a/.
und verweisen sogar a/inner/..
auf genau dasselbe Verzeichnis. Das bedeutet nicht, dass die Anwendung sie nicht selbst analysieren und ihnen unterschiedliche Bedeutungen geben kann, aber es ist einfacher, die Zeichenfolge einfach an den Kernel zu senden, der das Richtige tut.
Antwort4
Wenn ich mich recht erinnere, funktioniert das . in diesem Fall ähnlich wie ein *. Im Wesentlichen ist es ein Platzhalterzeichen.