ディレクトリを繰り返し、いくつかの名前を一致させて削除するシェルスクリプトにはいくつかの行があります。ファイルシステムの特定の領域は書き込み禁止です。これを維持したいのですが、プロンプトやエラーの他の表示をログにリダイレクトしたいと思います。彼らが会うとき。
スクリプトのこの時点で使用すると、rm -r /path/to/directory
スクリプトが出力されます。
rm: descend into write-protected directory /path/to/directory/subdirectory?
そのため、自分のデバイスにそのままにしておくと動作が中断され、[最終的に]タイムアウトします。
プロンプトに "n"を接続してこの動作を修正してみました。
yes n | rm -rv /path/to/directory
これにより、2つの望ましくない結果が生じる。
yes: standard output: Broken pipe; yes: write error
各ディレクトリの出力はい削除され、rm: descend into write-protected...
メッセージを標準出力に返さないでください。
これを行う正しい方法は何ですか?
修正する:yes n
@roaimaによると、パイプがあればインタラクティブではないので、実際にプロンプトをまったくパイプしませんrm
。実際には、いくつかの出力を得るためにインタラクティブ機能を利用していますが、インタラクティブ機能をオフにするとプログラムがエラーで終了するため、これは皮肉です。保護されたファイルの名前が必要なので、エラーを無視したくありません(たとえば、|| true
SEの他の場所で見たように追加)
答え1
rm
stdinが端末の場合、書き込み不可能な宛先の確認が要求されます。-i
一方、確認のためにフラグがオンになります。みんなターゲット。明らかに、これらの方法のどれもにyes n
パイプを接続する簡単なソリューションには適していないので、rm
他の方法を使用する必要があります。
GNU findを使用して、1つ以上の書き込みモードビットが設定されているすべてのオブジェクトを削除します(通常は最初にテストを実行するので-print
はなく最初に使用します-delete
)。
find dir/ -perm /0222 -delete
または、書き込みモードビットが1つ以上設定されている(*)ファイルをすべて削除し、書き込み不可能なディレクトリの内容をスキップします。
find . -type d ! -perm /0222 -prune -o ! -type d -perm /0222 -exec rm {} +
(*実際にディレクトリを除くすべて)
-delete
深さ優先検索(少なくともGNU findでは)を意味し、機能しないため、-prune
ここでは使用できません。その後、書き込み可能な空のディレクトリを削除できます。
find . -type d -perm /0222 -delete
空でないディレクトリに対してエラーが発生します。
-perm /0222
「全ての書込みビットがセットされている」を意味し、反義語は! -perm /0222
「書込みビットがセットされていない」である。
他のバージョンの find では、代わりに+0222
を使用/0222
してください。 (GNUのマニュアルページによると、前者はPOSIXの要件と競合するため、廃止されました。)
書き込み不可能なファイルやディレクトリを見つけるには、同様に使用できます。
find . ! -perm /0222
書き込み不可能なディレクトリの内容を再帰的に一覧表示するのは少し難しいですが、GNUツールを使用すると次のように動作できます。
find . ! -perm /0222 -print0 | xargs -0 find
答え2
他のツールを試してみることをお勧めします。 Find コマンドは、構文規則の一部を習得すると、非常に強力で使いやすいです。
例:
検索/ディレクトリ - 名前パターン -perm g = w -exec /bin/rm {} \;
次に、「書き込み」グループ権限(0020 8進数chmod形式と論理的に一致)を持つ/ディレクトリの下のすべてのファイルとサブフォルダを検索し、ファイルを削除します。
あるいは、印刷オプションを使用して実行し、検索パターンに一致するファイルのリストを取得することもできます。
例: find/ディレクトリ名-パターン-perm 0111-print