次のコマンドの違いは何ですか?
mv foo bar
mv foo/ bar/
mv foo/ bar
mv foo bar/
それとも違いはありませんか?または、使用されているコマンドに依存しますか?たとえば、使用するバージョンに応じてrsyncの動作が少し変わることを読んだと思います。誰かが良い説明を持っているので、私はもう推測する必要がなく、私が何をしているのかを知っているように感じますか?
次のコマンドの違いは何ですか?
mv foo bar
mv foo/ bar/
mv foo/ bar
mv foo bar/
それとも違いはありませんか?または、使用されているコマンドに依存しますか?たとえば、使用するバージョンに応じてrsyncの動作が少し変わることを読んだと思います。誰かが良い説明を持っているので、私はもう推測する必要がなく、私が何をしているのかを知っているように感じますか?
回答:
多くの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
or -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
すでにjsalonenが言ったように、これらのコマンドは実際にはディレクトリである場合foo
、同じ結果になりbar
ます。
ただし、foo
とbar
がディレクトリでない場合、末尾にスラッシュを追加するとコマンドは失敗し、追加しないと成功します。つまり、コマンドが成功した場合、おそらく意図した結果が得られないでしょう。実際に、あなたも失うデータであればできたfoo
とbar
しているファイルは、(bar
上書きされます)。
ファイルではなくディレクトリを指定する場合は、コマンドをより堅牢にするため、末尾のスラッシュを使用するfoo
必要bar
があります。ディレクトリまたはディレクトリであるという期待が失敗すると、予期しない結果になるのではなく、コマンドが正常に失敗します。
また、一部の(まれな)コマンドは、ディレクトリがある場合でも、末尾のスラッシュの存在によって異なる動作をします(1つの例ですrsync
)。