Unix: ukośnik po nazwach katalogów lub nie

13

Jaka jest różnica między następującymi poleceniami?

mv foo bar
mv foo/ bar/
mv foo/ bar
mv foo bar/

Czy nie ma różnicy? Czy to zależy od użytej komendy? Pomyśl na przykład, że przeczytałem, że zachowanie rsync zmienia się nieco w zależności od używanej wersji. Czy ktoś ma dobre wytłumaczenie, więc nie muszę już zgadywać i czuć, że wiem, co robię?

Svish
źródło
2
Dotyczy to rsync. Rozpoczyna kopiowanie albo z samym katalogiem, albo z elementami pod nim, w zależności od tego, czy odpowiednio pominiesz, czy dodasz końcowy ukośnik.
maxelost
@maxelost: Czy możesz dodać odpowiedź z kilkoma przykładami, aby było jasne, co robi?
Svish,
Myślę, że Mikel odpowiedział wyraźnie poniżej.
maxelost

Odpowiedzi:

17

Wiele narzędzi uniksowych traktuje dowiązania symboliczne w różny sposób w zależności od tego, czy występuje ukośnik końcowy.

To zachowanie jest opisane w dokumentacji POSIX Symbolic Link i jest również wspomniane w dokumentacji GNU coreutils .

Zasadniczo ukośnik końcowy oznacza śledzenie (lub „dereferencję”) dowiązania symbolicznego.

Na przykład w poniższym kodzie dirlinkoznacza dowiązanie symboliczne, ale dirlink/oznacza katalog, do którego prowadzi dowiązanie symboliczne. rmnie usunie katalogu, chyba że powiesz rm -r, ale rmbez opcji z przyjemnością usunie dowiązanie symboliczne.

$ 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

Jest także przydatny do przeglądania uprawnień do katalogu, bez konieczności zawracania sobie głowy tym, czy katalog jest prawdziwym katalogiem, czy tylko dowiązaniem symbolicznym do katalogu.

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

i nadal działa dla zwykłych katalogów:

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

Innym przykładem jest findpolecenie. Jeśli pathpoprosisz go o wyszukiwanie, jest to dowiązanie symboliczne, domyślnie nie podąży ono za dowiązaniem symbolicznym, co oznacza, że ​​przetwarza tylko dowiązanie symboliczne. Dodanie ukośnika powoduje, że traktuje dowiązanie symboliczne jako katalog, do którego prowadzi dowiązanie.

$ find dir
dir
dir/file
$ find dirlink
dirlink
$ find dirlink/
dirlink/
dirlink/file

(niektóre wersje find mają opcję -followlub -L, ale dzięki temu podążają za wszystkimi dowiązaniami symbolicznymi, nie tylko pierwszymi)


To rsync, czy powinieneś dodać ukośnik, zależy od tego, czy chcesz, aby katalog, który kopiujesz, był podkatalogiem, czy nie.

$ 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

Innymi słowy:

  • rsync dir dir.bakkopiuje dirdo dir.bak, robiąc w dirśrodkudir.bak
  • rsync dir/ dir.bakkopiuje całą zawartość dirbez robienia w dirśrodkudir.bak
Mikel
źródło
2

Jak jsalonen już powiedział, polecenia te rzeczywiście mają identyczne wyniki, jeśli fooi barsą, jak w rzeczywistości, katalogów.

Jednakże, jeśli fooi barnie są katalogi, a następnie polecenie zakończy się niepowodzeniem, jeśli dołączyć ukośnik i uda, jeśli nie. Chodzi o to, że jeśli polecenie się powiedzie, prawdopodobnie nie uzyska oczekiwanego rezultatu. W rzeczywistości, można nawet stracić, jeśli dane fooi barsą pliki ( barbędzie nadpisane).

Jeśli twoim zamiarem jest, aby określić, katalogów i plików nie, to należy użyć końcowy ukośnik, ponieważ to sprawia, że komenda bardziej wytrzymałe: jeśli oczekiwanie, że fooalbo barsą katalogi nie powiedzie się, wówczas komenda nie powiedzie się z wdziękiem, zamiast nieoczekiwane rezultaty.

Ponadto niektóre (rzadkie) polecenia zachowują się inaczej w zależności od obecności końcowego ukośnika, nawet w przypadku katalogów (jednym przykładem jest rsync).

Etienne Dechamps
źródło
Tak, jak sugerowałem, polecenia mogą, ale nie muszą, dobrze radzić sobie z ukośnikami. Bardzo dobrze, że podałeś rsync jako przykład!
jsalonen