次のコマンドの違いは何ですか?
mv foo bar
mv foo/ bar/
mv foo/ bar
mv foo bar/
それとも違いはないのでしょうか? それとも、使用するコマンドによって異なりますか? たとえば、rsync の動作は、使用するバージョンによって少し変わると読んだことがあります。もう推測せずに、自分が何をしているのかがわかるような、良い説明をしてくれる人はいませんか?
答え1
多くの 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/
もう 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.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
)。