Was ist der Unterschied zwischen den folgenden Befehlen?
mv foo bar
mv foo/ bar/
mv foo/ bar
mv foo bar/
Oder gibt es da keinen Unterschied? Oder hängt es vom verwendeten Befehl ab? Ich habe zum Beispiel gelesen, dass sich das Verhalten von rsync je nach verwendeter Version etwas ändert. Hat jemand eine gute Erklärung, damit ich nicht mehr raten muss und das Gefühl habe, zu wissen, was ich tue?
Antwort1
Viele Unix-Dienstprogramme behandeln symbolische Links unterschiedlich, je nachdem, ob ein abschließender Schrägstrich vorhanden ist oder nicht.
Dieses Verhalten wird beschrieben in derPOSIX Symbolic Link-Dokumentationund wird auch erwähnt in derGNU Coreutils-Dokumentation.
Der abschließende Schrägstrich bedeutet grundsätzlich, dass dem symbolischen Link gefolgt werden soll (oder dieser „dereferenziert“ werden soll).
Beispielsweise dirlink
bedeutet im folgenden Code nicht den symbolischen Link, sondern dirlink/
das Verzeichnis, auf das der symbolische Link verweist. rm
entfernt kein Verzeichnis, wenn Sie nichts anderes angeben rm -r
, entfernt aber rm
ohne Optionen problemlos einen symbolischen Link.
$ mkdir dir
$ ln -s dir dirlink
$ ls -l
total 4
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:26 dir
lrwxrwxrwx 1 mikel mikel 3 2011-02-02 22:26 dirlink -> dir
$ ls -l
total 4
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:26 dir
lrwxrwxrwx 1 mikel mikel 3 2011-02-02 22:26 dirlink -> dir
$ rm dirlink/
rm: cannot remove `dirlink/': Is a directory
$ rm dirlink
$ ls -l
total 4
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:26 dir
Es ist auch nützlich, um die Berechtigungen eines Verzeichnisses anzuzeigen, ohne sich darum kümmern zu müssen, ob es sich bei dem Verzeichnis um ein echtes Verzeichnis oder nur um einen symbolischen Link zu einem Verzeichnis handelt.
$ ls -ld dirlink
lrwxrwxrwx 1 mikel mikel 3 2011-02-02 22:46 dirlink -> dir
$ ls -ld dirlink/
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:46 dirlink/
und es funktioniert immer noch für normale Verzeichnisse:
$ ls -ld dir
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:46 dir
$ ls -ld dir/
drwxr-xr-x 2 mikel mikel 4096 2011-02-02 22:46 dir/
Ein weiteres Beispiel ist der find
Befehl. Wenn es sich bei dem path
von Ihnen angeforderten Suchpfad um einen symbolischen Link handelt, wird dieser standardmäßig nicht befolgt, d. h., er verarbeitet nur den symbolischen Link. Durch das Hinzufügen eines abschließenden Schrägstrichs wird der symbolische Link als das Verzeichnis behandelt, auf das der Link verweist.
$ find dir
dir
dir/file
$ find dirlink
dirlink
$ find dirlink/
dirlink/
dirlink/file
(einige Versionen von find haben eine -follow
oder -L
Option, aber dadurch werden alle symbolischen Links verfolgt, nicht nur der erste)
Ob Sie im Fall von rsync
einen Schrägstrich anhängen sollten, hängt davon ab, ob das zu kopierende Verzeichnis ein Unterverzeichnis sein soll oder nicht.
$ mkdir dir
$ touch dir/file
$ rsync -r dir dir.bak
$ find .
.
./dir
./dir/file
./dir.bak
./dir.bak/dir
./dir.bak/dir/file
$ rm -r dir.bak
$ rsync -r dir/ dir.bak
$ find .
.
./dir
./dir/file
./dir.bak
./dir.bak/file
Mit anderen Worten:
rsync dir dir.bak
Kopiendir
indir.bak
, machendir
innerhalbdir.bak
rsync dir/ dir.bak
kopiert den gesamten Inhalt vondir
, ohnedir
darindir.bak
Antwort2
Wie jsalonen bereits sagte, haben diese Befehle tatsächlich identische Ergebnisse, wenn es foo
sich bar
tatsächlich um Verzeichnisse handelt.
Wenn foo
und jedoch bar
keine Verzeichnisse sind, schlägt der Befehl fehl, wenn Sie einen abschließenden Schrägstrich anhängen, und ist erfolgreich, wenn Sie dies nicht tun. Die Sache ist, dass der Befehl, wenn er erfolgreich ist, wahrscheinlich nicht das gewünschte Ergebnis liefert. Tatsächlich könnten Sie sogar Daten verlieren, wenn foo
und bar
Dateien sind ( bar
würden überschrieben).
Wenn Sie Verzeichnisse und keine Dateien angeben möchten, dannsollenverwenden Sie einen abschließenden Schrägstrich, da dieser den Befehl robuster macht: Wenn die Erwartung, dass foo
oder bar
Verzeichnisse sind, fehlschlägt, schlägt der Befehl ordnungsgemäß fehl, anstatt unerwartete Ergebnisse zu liefern.
Außerdem verhalten sich einige (seltene) Befehle je nach Vorhandensein eines abschließenden Schrägstrichs anders, sogar bei Verzeichnissen (ein Beispiel ist rsync
).