Unix: ディレクトリ名の後にスラッシュをつけるかどうか

Unix: ディレクトリ名の後にスラッシュをつけるかどうか

次のコマンドの違いは何ですか?

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

それとも違いはないのでしょうか? それとも、使用するコマンドによって異なりますか? たとえば、rsync の動作は、使用するバージョンによって少し変わると読んだことがあります。もう推測せずに、自分が何をしているのかがわかるような、良い説明をしてくれる人はいませんか?

答え1

多くの Unix ユーティリティは、末尾のスラッシュがあるかどうかに応じて、シンボリックリンクを異なる方法で処理します。

この動作については、POSIX シンボリック リンクのドキュメントまた、GNU coreutils ドキュメント

基本的に、末尾のスラッシュはシンボリックリンクをたどる(または「逆参照する」)ことを意味します。

たとえば、以下のコードでは、 はdirlinkシンボリックリンクを意味しますが、 はdirlink/シンボリックリンクが指すディレクトリを意味します。 rmを指定しない限り、ディレクトリは削除されませんがrm -rrmオプションを指定しないと、シンボリックリンクが削除されます。

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

もう 1 つの例は、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.bakdirにコピーしてdir.bakdir内部に作成するdir.bak
  • rsync dir/ dir.bakのすべての内容をコピーしますdirdirdir.bak

答え2

jsalonen がすでに述べたように、 と が実際のところディレクトリである場合、これらのコマンドは確かに同一の結果をもたらしfooますbar

ただし、fooと がbarディレクトリでない場合、末尾にスラッシュを追加するとコマンドは失敗し、追加しないと成功します。ただし、コマンドが成功したとしても、おそらく意図した結果にはならないでしょう。実際、 とfoobarファイルである場合は、データが失われる可能性もあります (bar上書きされます)。

ファイルではなくディレクトリを指定する場合は、すべきfoo末尾にスラッシュを使用すると、コマンドがより堅牢になります。つまり、またはがディレクトリであるという期待がbar失敗した場合、予期しない結果になるのではなく、コマンドは正常に失敗します。

また、一部の(まれな)コマンドは、ディレクトリの場合でも、末尾のスラッシュの有無に応じて動作が異なります(一例はrsync)。

関連情報