パイプとアンパサンドでgrepを使用して、findからエラーをフィルタリングする


22

cygdriveでファイルを見つけるためにcygwinを使用しています。

ただし、アクセス許可が拒否されたメッセージを抑制する必要があります(そうでない場合、結果はエラーメッセージに隠されます)。次のコマンドが機能します。

find -name 'myfile.*' |& grep -v "Permission denied"

アンパサンドをこのコマンドに入力する必要がある理由がわかりません。これは機能するはずですが、機能しません。

find -name 'myfile.*' | grep -v "Permission denied"

アンパサンドの意味を説明してください。

回答:


24

Unixライクなシステムでは、2つの出力パスがあり、変更しないままにしておくと画面に出力が送信されます。標準エラー(またはstderr)は、ほとんどの障害とエラー状態をキャプチャするものです。

stderrの許可拒否メッセージを「通常の出力」と同じ出力ストリームに渡すには、2つを組み合わせる必要があります。この例ではgrep -v、適切に操作するために、stdout(標準出力)とstderrを表示される難解な構文と組み合わせます。

GNU Bashのマニュアルのセクション3.2.2パイプライン

|&」を使用すると、command1の標準エラーが標準出力に加えて、パイプを介してcommand2の標準入力に接続されます。それは略記です2>&1 |。この標準エラーの標準出力への暗黙的なリダイレクトは、コマンドで指定されたリダイレクトの後に実行されます。

また、geirhaが指摘しているように、stderrの出力を単に取り除きたい場合は、次のようなことをしたいと思うでしょう。

find -name 'myfile.*' 2> /dev/null

多分

find -name 'myfile.*' 2> /tmp/errorlog

またfind、出力を渡すなど、コマンドの文字列がある場合は、コマンドのxargsパイプライン全体をかっこで囲んで、コマンドのすべてのコンポーネントからの出力をキャプチャする必要があります。例えば、

(find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 )  2> /dev/null

括弧を省略し、代わりにこれを行った場合-

find | egrep ^[RS].[0-9]+/.svg] | xargs head -1 2> /dev/null

findまたはegrepからのアクセスが拒否されたエラーが表示されますが、stderrはxargsにリダイレクトされます。

これまで見てきたように、テスト実行中に内容を表示した後にのみstderrを破棄する可能性があります。

GNU findと、私が知る限り、POSIX準拠find-printオプションは暗黙的であることに注意してください。必要に応じて明示的に指定することもできます。



1
@LukeExtonはい。他のシェルで2>&1 |は、代わりに使用できます|&(つまり、stderrを明示的にstdoutにリダイレクトし、パイプライン内の次のコマンドにパイプすることができます)。
エリアケイガン

2> >( grep filter )また、便利です
user1133275


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.