rm -rf はシンボリックリンクをたどりますか?

rm -rf はシンボリックリンクをたどりますか?

次のようなディレクトリがあります:

$ ls -l
total 899166
drwxr-xr-x 12 me scicomp       324 Jan 24 13:47 data
-rw-r--r--  1 me scicomp     84188 Jan 24 13:47 lod-thin-1.000000-0.010000-0.030000.rda
drwxr-xr-x  2 me scicomp       808 Jan 24 13:47 log
lrwxrwxrwx  1 me scicomp        17 Jan 25 09:41 msg -> /home/me/msg

そして、 を使用して削除したいと思いますrm -r

rm -rしかし、シンボリックリンクをたどってそのディレクトリ内のすべてのものを削除してしまうのではない かと心配です(これは非常に悪いことです)。

これについてはマニュアルページには何も記載されていません。rm -rfこのディレクトリより上のディレクトリから実行した場合、正確にはどのような動作になるのでしょうか?

答え1

例 1: 別のディレクトリへのソフト リンクを含むディレクトリを削除します。

susam@nifty:~/so$ mkdir foo bar
susam@nifty:~/so$ touch bar/a.txt
susam@nifty:~/so$ ln -s /home/susam/so/bar/ foo/baz
susam@nifty:~/so$ tree
.
├── bar
│   └── a.txt
└── foo
    └── baz -> /home/susam/so/bar/

3 directories, 1 file
susam@nifty:~/so$ rm -r foo
susam@nifty:~/so$ tree
.
└── bar
    └── a.txt

1 directory, 1 file
susam@nifty:~/so$

したがって、ソフトリンクのターゲットは存続していることがわかります。

例2: ディレクトリへのソフトリンクの削除

susam@nifty:~/so$ ln -s /home/susam/so/bar baz
susam@nifty:~/so$ tree
.
├── bar
│   └── a.txt
└── baz -> /home/susam/so/bar

2 directories, 1 file
susam@nifty:~/so$ rm -r baz
susam@nifty:~/so$ tree
.
└── bar
    └── a.txt

1 directory, 1 file
susam@nifty:~/so$

ソフトリンクのみが削除されます。ソフトリンクのターゲットは存続します。

例3: ソフトリンクのターゲットを削除しようとする

susam@nifty:~/so$ ln -s /home/susam/so/bar baz
susam@nifty:~/so$ tree
.
├── bar
│   └── a.txt
└── baz -> /home/susam/so/bar

2 directories, 1 file
susam@nifty:~/so$ rm -r baz/
rm: cannot remove 'baz/': Not a directory
susam@nifty:~/so$ tree
.
├── bar
└── baz -> /home/susam/so/bar

2 directories, 0 files

シンボリックリンクのターゲット内のファイルは存続しません。

上記の実験は、Debian GNU/Linux 9.0 (stretch) システムで実行されました。

答え2

ls を実行したディレクトリを rm -rf すれば、/home/me/msg ディレクトリは安全です。シンボリックリンク自体のみが削除され、それが指すディレクトリは削除されません。

注意すべき唯一のことは、「rm -rf msg/」(末尾にスラッシュを付けて) のようなものを呼び出す場合です。これは、msg シンボリックリンク自体ではなく、msg が指すディレクトリを削除するため、実行しないでください。

答え3

rmファイルとディレクトリを削除します。ファイルがシンボリックリンクの場合、ターゲットではなくリンクが削除されます。シンボリックリンクは解釈されません。たとえば、「壊れたリンク」を削除するときの動作はどうなりますか? rm は失敗を示すために 0 以外の値ではなく 0 で終了します。

関連情報