質問: 標準エラーストリーム(stderr)をgrepする方法 オーディオクリップのメタ情報を取得するためにffmpegを使用しています。しかし、私はそれをgrepすることができません。 $ ffmpeg -i 01-daemon.mp3 |grep -i duration ffmpeg version svn-r15261, copyright (c) 2000-2008 fabrice bellard, et al. configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib --mandir=/usr/share/man --arch=i386 --extra-cflags=-o2 ... 私がチェックしたところ、このffmpeg出力はstderrに送信されます。$ ffmpeg -i 01-daemon.mp3 2> /dev/null したがって、grepはエラーストリームを読み取って一致する行をキャッチすることができないと思います。 grepでエラーストリームを読み取れるようにするにはどうすればよいですか? nixcraft リンクを使用して、標準エラーストリームを標準出力ストリームにリダイレクトすると、grepが機能しました。$ ffmpeg -i 01-daemon.mp3 2>&1 | grep -i duration duration: 01:15:12.33, start: 0.000000, bitrate: 64 kb/s しかし、stderrをstdoutにリダイレクトしたくない場合はどうでしょうか。
回答: 通常のシェル(zshも含む)はどれも、stdoutからstdin以外のパイプを許可しません。ただし、すべてのbourneスタイルのシェルは、ファイル記述子の再割り当てをサポートしています(1>&2など)。したがって、stdoutを一時的にfd 3に迂回させ、stderrをstdoutに迂回させ、後でfd 3をstdoutに戻すことができます。 stuffがstdoutにいくつかの出力を生成し、stderrに一部の出力を生成し、標準出力をそのままにしてエラー出力にfilterを適用する場合は、{ stuff 2>&1 1>&3 | filter 1>&2; } 3>&1を使用できます。$ stuff () { echo standard output echo more output echo standard error 1>&2 echo more error 1>&2 } $ filter () { grep a } $ { stuff 2>&1 1>&3 | filter 1>&2; } 3>&1 standard output more output standard error