「rm *」を実行しているときに「一致が見つかりません」を取り除く方法


21

を使用するとzsh、適合しないパターンを選択した場合、rmおよび出力をリダイレクトした場合でも、「一致が見つかりません」というメッセージが表示されます。

# rm * > /dev/zero 2>&1
  zsh: no matches found: *

このメッセージを削除するにはどうすればよいですか?


現在のディレクトリ内のすべてを削除しようとしていますか?現在のディレクトリは何ですか?
cutrightjm

使用することもできますsetopt extended_glob(またはプレーンrm * >/dev/null 2>&1)でも、実際には回避する必要がありますrm *。これは
まったく

そうでは/dev/nullなく本当に沈むべきdev/zeroです。また、stderrリダイレクトには&; がありません。あるはずです2>&1
ロアイマ

エラーメッセージはzsh、コマンド自体の実行時ではなく、コマンドの評価中に生成されます(エラーのため、コマンドは実行されません)。ここでの出力リダイレクトは、コマンドの出力にのみ影響し、シェル自体には影響しません。
アデフォン

回答:


41

この動作は、Zshのnomatchオプションによって制御されます。デフォルトでは、コマンドラインにグロビング式が含まれていて、それが何にも一致しない場合、Zshは表示されているエラーメッセージを出力し、コマンドをまったく実行しません。これを無効にするには、次を実行します

setopt +o nomatch

次に、何にも一致しないグロビング式はそのまま残され、エラーメッセージが表示されますrm(を使用して無効にすることができ-fますが、そうでない場合は削除を強制するため、それは悪い考えです)をしたい)。


4
動作は、によって制御されているnullglobcshnullglobオプション。nullglobが設定されていて、一致するファイルが見つからない場合、エラーを生成する代わりに、パターンが引数リストから削除されます。cshnullglobコマンドのすべてのパターンが一致しない場合を除き、設定は同様の効果があります。その場合、エラーが報告されます。注:を設定nullglobまたはcshnullglobオーバーライドしますnomatchnullglobglob修飾子を使用して単一パターンを設定することもできますNrm *(N)
アデフォン

nomatch理想的とは言えませんが、それがBourneのようなシェルの機能です。パターンが一致しない場合、そのままrm(!)に渡されrm、エラーが発生します。さらに悪い*.[ch]場合、たとえば、パターンの間違ったファイルが削除される可能性があります。
ステファンシャゼラス

9

代わりに何をしたいですか?rmまったく実行されません(1)?*他のBourneのようなシェル(2)のようなリテラル引数で実行しますか?引数なしで実行します(3)?

  1. files=(*(N)); (($#files)) && rm -- $files。または(rm -- *) 2> /dev/null、それはまたrm、愚かなことになる本物のエラーを隠します。あなたはzshエラーを捨てることができますが、rmコマンドのstderrを復元します(rm -- * 2>&3 3>&-) 3>&2 2> /dev/null
  2. emulate sh -c 'rm -- *' 2> /dev/null。ように続いてshいるzsh今、その単一のコマンドライン用のエミュレートされ、非マッチングは*にそのまま渡されるrmと、rmそのよう文句*ファイルが存在しません。私たちは抑制rmあなたが行うようの標準エラー出力をshエラーメッセージことを抑制するためには、それが本物でエラーを非表示と同じように、再び、それは愚かだrmの不正行為によって生じた誤差とは対照的に、shリテラル渡し*にしますrmrm -f '*'存在しない*ファイルについて文句を言うことはありませんが、そうすることができますemulate sh -c 'rm -f -- *'
  3. rm -- *(N)rm、しかし、再び、任意の引数を渡されていないときではないが文句を言うでしょうrm -frm -f -- *(N)

一般に、rm -fすべてのファイルを削除し、ファイルを削除できなかった場合、またはIOWがrm戻った後もIOWが残っている場合にのみエラーを取得する場合に使用するコマンドです。また、通常-f、スクリプトで使用して、特定の状況でユーザーにプロンプ​​トが出されないようにします。

ここでrmは、グロブが一致しないときに呼び出すのは間違っています。sh1つの行動が間違っています。それはのようなパターンのために無害だ*が、同様に1つずつ*.[ch]渡し、*.[ch]それが引き起こす可能性が一致しない場合されて、*.[ch]ファイルを誤って削除します:

$ ls
*.[ch]  foo.txt
$ zsh -c 'rm *.[ch]'
zsh:1: no matches found: *.[ch]
$ ls
*.[ch]  foo.txt
$ sh -c 'rm *.[ch]'
$ ls
foo.txt

エラーで失敗すると行うための最も賢明なことで、何でzsh(とfishcshtcshbash -o failglob、オリジナルのUnixシェル)ありません。

そして、あなたがその特別なケースに気をつけたいなら、上記のケース(1)のように、zshその(N)glob修飾子(noglob)で簡単にします。fish(少なくとも最近のバージョンでは)コマンドに対して暗黙的なnoglob実行するため、さらに簡単になりsetます。したがって、そこに相当するものは次のようになります。

set files *
if count $files > /dev/null
  rm -f -- $files
end

詳細については、nullglobがデフォルトはない理由を参照してください。


1。厳密に言えば、それshはBourneシェル(1979年のUnix V7以降)以来です。shグロブ名が由来/etc/globする引用符で囲まれていないワイルドカードを呼び出す)の以前のバージョンは、またはのように動作しました。それらの1つに一致がありました)。この動作は、Bourneシェルによって壊れていました。cshzsh -o cshnullglob/etc/glob


彼はrm、シェルからではなく、エラーメッセージを受け取ることを期待していると思います。「rm: `* 'を削除できません:そのようなファイルまたはディレクトリはありません」など。
エマニュエル

@Emmanuel、それが2:emulate sh -c 'rm -- *'ボーンシェルの(バギーIMO)動作を取得するためです。
ステファンシャゼラス

@Stephane_Chazelasが書かれているように、2は彼が尋ねなかった質問に対する正しい答えです:)。
エマニュエル

@ Emmanuel、3つすべてが質問に答えます:「一致なし」エラーを取り除く方法。OPのコードはrmエラーを抑制します。これは、一致するファイルがない場合にエラーを抑制するために他のシェルで行うことであり、それにより、真のrmエラーも抑制されます。私の答えはそれを概説し、できればzshの振る舞いが望ましいことを示しています。
ステファンシャゼル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.