
次のような状況ではls -alh
total 0
drwxrwx--- 1 user http 20 Nov 30 08:08 .
drwxrws--- 1 user http 310 Nov 30 08:07 ..
drwx------ 1 http http 10 Nov 30 08:08 empty-subdir
drwx------ 1 http http 12 Nov 30 08:08 non-empty-subdir
2 つのサブディレクトリ (私が所有していない) が存在し、次のようにリストされます。
sudo ls empty-subdir -alh
total 0
drwx------ 1 http http 10 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..
sudo ls non-empty-subdir -alh
total 0
drwx------ 1 http http 12 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..
drwx------ 1 http http 0 Nov 30 08:08 subdir
2 つのサブディレクトリの違いは、空でないサブディレクトリにnon-empty-subdir
フォルダーが含まれていることです。
rm -rf
私の質問は、サブディレクトリを削除しようとすると次のような結果になるのは設計によるものかどうかです。
$ rm empty-subdir -rf
$ rm non-empty-subdir -rf
rm: cannot remove 'non-empty-subdir': Permission denied
$ ls -alh
total 0
drwxrwx---+ 1 user http 10 Nov 30 08:14 .
drwxrws---+ 1 user http 310 Nov 30 08:07 ..
drwx------+ 1 http http 12 Nov 30 08:08 non-empty-subdir
ディレクトリへの書き込み権限を持つユーザーは、ファイルのエントリや他のユーザーの空のサブディレクトリを削除することはできるが、空でないサブディレクトリ。
この質問に対する理想的な回答は、次のような情報を提供するものです。
- 概説した動作が他のマシンでも再現可能であることの確認(私の壊れたボックスの単なる癖ではない)
- その動作を説明する根拠(例:ユースケースはありますか?)
- システム間(BSD、Linuxなど)の違いがある場合の概要
アップデート: Ipor Sircer のコメントに関して、ACL 機能なしでシナリオを再テストしましたが、結果は同じでした。そのため、+
動作が ACL に関連している可能性があるという考えが生じないように、リストから es を削除するように質問を変更しました。
答え1
rmdir()
ディレクトリが空の場合にのみ、(システム コールを使用して) ディレクトリを削除できます。
rm -r dir
ディレクトリツリーのリーフからルート ( ) まで移動しながら、ディレクトリとその中のすべてのファイルを削除しますdir
。
ファイルを削除する場合 (rmdir()
ディレクトリの場合は 、unlink()
他の種類のファイルまたはそのバリアントの場合は を使用)、重要なのはファイル自体の権限ではなく、ファイルを削除するディレクトリの権限です (の場合のように、権限内の ビットによってさらに複雑になることに*at()
注意してください)。t
/tmp
そもそも、あなたは本当にファイル、ディレクトリからリンクを解除します(そして、削除するリンクが最後のリンクである場合、結果としてファイルは削除されます)、つまり、ディレクトリを変更するので、変更するそのディレクトリへの (書き込み) 権限。
削除できない理由は、変更権限がないため、まずnon-empty-dir
リンクを解除できないからです。ホーム ディレクトリへの書き込み/変更権限があるため、ホーム ディレクトリからリンクを解除する権限はありますが、空でないディレクトリを削除することはできません。subdir
non-empty-dir
non-empty-dir
あなたの場合、@PeterCordesがコメントで指摘したように、システムコールは(ディレクトリが空ではありません)エラーコードrmdir()
で失敗しますが、ENOTEMPTY
読むディレクトリへの権限がないため、ディレクトリを空にするためにrm
どのファイルとディレクトリ (を含む) のリンクを解除する必要があるかさえわかりませんsubdir
(書き込み権限がないため、知っていたとしてもリンクを解除できるわけではありません)。
次のような状況に陥ることもありますrm
できた書き込み専用ディレクトリの場合のように、その中にどのファイルが含まれているかがわかる場合にのみ、ディレクトリを削除します。
$ mkdir dir
$ touch dir/file
$ chmod a=,u=wx dir
$ ls -ld dir
d-wx------ 2 me me 4096 Nov 30 19:43 dir/
$ rm -rf dir
rm: cannot remove 'dir': Permission denied
file
それでも、次のファイルだけが含まれていることがわかったので、削除できました。
$ rm dir/file
$ rmdir dir
$
また、最近のUnixでは名前を変更できますnon-empty-dir
が、LinuxやFreeBSD(Solarisではない)では、ない別のディレクトリに移動します。そのディレクトリへの書き込み権限がある場合でも、(Linuxの場合は、関連するコードのコメント) そうすると、変更が必要になりますnon-empty-dir
(..
その中のエントリは別のディレクトリを指します)。
を削除すると、その中のおよびエントリもempty-dir
削除されるため、変更が必要になると主張する人もいるかもしれませんが、それでも、システムではそれが許可されています。..
.
答え2
ACL による潜在的な変更を無視すると、私のシステム (ACL なし) でこの動作を確認できます。
観察された動作は、次の 2 つの原則の論理的な帰結です。
1) ディレクトリの権限によって、ディレクトリを変更できるユーザー (つまり、ディレクトリ内のエントリを削除できるユーザー) が決まります。ディレクトリ内のエントリの権限は、この権限には影響しません。
2) ファイルを削除すると、i ノード、ブロック割り当てリストなどの関連情報を削除してクリーンアップする必要がある可能性があります。そのため、空でないサブディレクトリを削除するには、そのサブディレクトリに含まれるすべてのファイルをクリーンアップする必要があります。そうしないと、サブディレクトリに含まれるファイルにアクセスできなくなりますが、関連情報はクリーンアップされません。
したがって、empty-subdir
は、それが存在するディレクトリへの書き込み権限を持っているため、削除できます。 はnon-empty-subdir
、最初にこのサブディレクトリに含まれるファイルをクリーンアップする権限がないため、削除できません。
これには、まったく根拠も使用例もありません。サブディレクトリの再帰的なクリーンアップをカーネルに組み込むこともできましたが、オリジナルの Unix ではすべてがシンプルに保たれており、ユーザー空間ユーティリティで実現できる場合、再帰的なクリーンアップは複雑すぎたでしょう。
異なるフレーバー間の包括的な概要を提供することはできませんが、これはオリジナルの Unix での動作であり、Unix のどのフレーバーでも同じであると予想されます。異なる動作をする Unix のフレーバーがあったら驚きます。
答え3
あなたの説明を再現しようとして、 を実行しましたstrace rm -rf ./nonempty
。その結果、次のことがわかりました。
unlinkat(4, "subdir", AT_REMOVEDIR) = -1 EACCES (Permission denied)
マニュアルによるとunlinkat
(Linuxでは と同じですがunlink(2)
、強調は私が追加しました):
EACCES プロセスの実効UIDではパス名を含むディレクトリへの書き込みアクセスが許可されていない、または パス名内のディレクトリの 1 つに検索権限がありません(path_resolution(7)も参照。)
親ディレクトリ はx (検索) 権限nonempty
を付与していないため、削除できないという説明user
に基づいて、それは理にかなっています。EACCES
subdir