Unix: косая черта после имен каталогов или нет

13

В чем разница между следующими командами?

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

Или нет разницы? Или это зависит от используемой команды? Например, я прочитал, что поведение rsync немного меняется в зависимости от используемой версии. У кого-нибудь есть хорошее объяснение, чтобы мне больше не приходилось догадываться и чувствовать, что я знаю, что делаю?

Svish
источник
2
Это верно для rsync. Он начинает копирование либо с самого каталога, либо с элементов в нем, в зависимости от того, пропустили ли вы или добавили косую черту соответственно.
maxelost
@maxelost: Не могли бы вы добавить ответ с некоторыми примерами, чтобы было кристально ясно, что делает что?
Свиш
Я думаю, Микель ответил на это довольно четко ниже.
maxelost

Ответы:

17

Многие утилиты Unix обрабатывают символические ссылки по-разному в зависимости от того, есть ли косая черта.

Это поведение описано в документации по символическим ссылкам POSIX, а также в документации GNU coreutils .

По сути, косая черта означает следовать (или «разыменовывать») символическую ссылку.

Например, в приведенном ниже коде dirlinkозначает символическую ссылку, но dirlink/означает каталог, на который указывает символическая ссылка. rmне удалит каталог, если вы не скажете rm -r, но rmбез параметров удастся удалить символическую ссылку.

$ 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

Это также полезно для просмотра прав доступа к каталогу без необходимости беспокоиться о том, является ли каталог настоящим каталогом или просто символической ссылкой на каталог.

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

и это все еще работает для обычных каталогов:

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

Другой пример - findкоманда. Если pathвы просите его найти символическую ссылку, по умолчанию она не будет следовать символической ссылке, то есть обрабатывает только символическую ссылку. Добавление косой черты заставляет ее обрабатывать символическую ссылку как каталог, на который указывает ссылка.

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

(в некоторых версиях find есть опция -followor -L, но она позволяет следовать всем символическим ссылкам, а не только первой)


В случае rsync, если вы должны добавить косую черту, зависит от того, хотите ли вы, чтобы каталог, который вы копируете, был подкаталогом или нет.

$ 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

Другими словами:

  • rsync dir dir.bakкопирует dirв dir.bak, делая dirвнутриdir.bak
  • rsync dir/ dir.bakкопирует все содержимое dir, не делая dirвнутриdir.bak
Mikel
источник
2

Как уже сказал jsalonen, эти команды действительно имеют идентичные результаты, если fooи barявляются, по сути, каталогами.

Однако, если fooи barне являются каталогами, то команда завершится неудачно, если вы добавите завершающий слеш, и завершится успешно, если вы этого не сделаете. Дело в том, что если команда будет выполнена успешно, то, вероятно, у нее не будет ожидаемого результата. На самом деле, вы можете даже потерять данные, если fooи barфайлы ( barбудут перезаписаны).

Если вы намереваетесь указывать каталоги, а не файлы, то вам следует использовать косую черту, поскольку это делает команду более устойчивой: если ожидание того, что каталоги fooили barявляются каталогами, не удастся выполнить, то команда будет выполнена изящно, вместо неожиданных результатов.

Кроме того, некоторые (редкие) команды ведут себя по-разному в зависимости от наличия косой черты, даже с каталогами (один из примеров rsync).

Этьен Дечам
источник
Да, как я и предполагал, команды могут или не могут справиться с хорошо сложенными косыми чертами. Очень хорошо, что вы привели rsync в качестве примера!
jsalonen