13

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

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

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

2 ответа2

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 есть -follow или -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
2

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .