2つ以上のサブディレクトリ内のすべてのファイルを削除しようとしていますが、zsh
ディレクトリが空の場合、次のディレクトリは無視され、ファイルは保持されます。
例:
$ mkdir dir1
$ mkdir dir2
$ touch dir2/blah
# avoid the zsh safety prompt; this may not be necessary for this
# example, just for ease of use here
$ setopt rm_star_silent
$ rm -r dir1/* dir2/*
zsh: no matches found: dir1/*
$ ls dir2
blah
rm
Bashでは、すでに空のディレクトリが進行を中断することなくdir2
削除さdir2/blah
れます。
この関数とは何ですか? のように動作させるzsh
方法はありますか?rm
bash
答え1
bash
とは異なり、zsh
デフォルトではファイル名生成パターンと一致するものがない場合はエラーが報告されます。この動作は、全体的に、またはモードごとに変更できます。
NULL_GLOB
グローバルな不一致パターンによるエラーメッセージを防ぐには、次のいずれかのオプションを設定できますCSH_NULL_GLOB
。
setopt nullglob
パターンに一致するものがない場合は、パラメータリストから削除されます。エラーメッセージは印刷されません。あなたの例では
rm dir1/* dir2/*
ただ拡張されます
rm dir2/blah
setopt cshnullglob
また、一致しないパターンを削除し、一致するパターンがない場合はエラーメッセージを出力しません。
単一パターンのエラーメッセージを回避するには、このパターンに対してオプションが有効になっているかのN
ように動作するglob修飾子を使用できます。NULL_GLOB
rm dir1/*(N) dir2/*(N)
これは次のように拡張される予定です。
rm dir2/blah
答え2
最善の方法は、2つのディレクトリのファイルと一致する単一のグローブにすることです。
rm (dir1|dir2)/*
これにより、ファイルが見つからない場合でもコマンドは実行されません。
ただしdir1
、dir2
含めることはできませんのでご注意ください/
。
このような場合は、次のことができます。
files=(foo/bar/*(N) bar/baz/*(N))
if ((#files)); then
rm $files
else
echo >&2 No matching file
fi
または、cshnullglob
cshまたはBourne shの以前の動作を取得するために使用されます。これは、bash
一致しないグローバルオブジェクトがコマンドに渡される偽(IMO)動作に戻るよりも優れています。次のことができます。
set +o nomatch
答え3
良い説明はここにあります。
https://superuser.com/questions/584249/using-wildcards-in-commands-with-zsh
主な点は次のとおりです。
By default, ZSH will generate the filenames and throw an error before executing the command if it founds no matches.
空のディレクトリでは一致が生成されないため、エラーが発生します。答えが示すように、次のことができます。
- パラメータを引用符で囲む(例
rm -r "dir1/*" "dir2/*"
:) unsetopt nomatch
ファイルに設定する.zshrc
か- コマンドに環境変数を使用できます
noglob
(例noglob rm -r dir1/* dir2/*
:)