TL;DR:
$ cmd 2> >(stderr-filter >&2)
例:
% cat /non-existant 2> >(tr o X >&2)
cat: /nXn-existant: NX such file Xr directXry
%
これは、bash と zsh の両方で機能します。最近では Bash はかなり普及していますが、POSIX sh
の (本当に危険な) ソリューションが本当に必要な場合は、
説明
これを行う最も簡単な方法は、プロセス置換を介して STDERR をリダイレクトすることです。
<ブロック引用>プロセス置換により、プロセスの入力または出力をファイル名を使用して参照できます。
の形を取ります>(list)
プロセス リストは非同期で実行され、その入力または出力はファイル名として表示されます。
したがって、プロセス置換で得られるのはファイル名です。
あなたができるように:
$ cmd 2> filename
できます
$ cmd 2> >(filter >&2)
>&2
リダイレクトの filter
の STDOUT を元の STDERR に戻します。
TL;DR:(bash と zsh)
$ cmd 2> >(stderr-filter >&2)
例:
% cat /non-existant 2> >(tr o X >&2)
cat: /nXn-existant: NX such file Xr directXry
%
StackExchange ネットワーク上の多くの回答は次の形式をとっています:
cat /non-existant 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g'
これには、ファイル記述子 3 が他の目的で使用されていないという前提が組み込まれています。
代わりに、名前付きファイル記述子と {ba,z}sh
を使用してください 次に利用可能なファイル記述子を割り当てます>=10:
cat /non-existant {tmp}>&1 1>&2 2>&$tmp {tmp}>&- | sed 's/e/E/g'
名前付きファイル記述子は POSIX sh
ではサポートされていないことに注意してください .
上記のもう 1 つの問題は、STDOUT と STDERR を元の値に再度スワップしない限り、コマンドを別のコマンドにパイプできないことです。
POSIX sh
で以降のパイプを許可するには 、(それでも FD 3 が使用されていないと仮定すると) 複雑になります:
(cmd 2>&1 >&3 3>&- | stderr-filter >&2 3>&-) 3>&1
したがって、この仮定と危険な構文を考えると、より単純な bash
を使用する方がよいでしょう。 /zsh
上記の TL;DR に示され、ここで説明されている構文。
実用的なデモンストレーション、stderr のみを grep:
$ ls -l . noexistABC noexistXYZ
ls: cannot access 'noexistABC': No such file or directory
ls: cannot access 'noexistXYZ': No such file or directory
.:
total 4
-rw-rw-r-- 1 frank frank 0 Aug 19 12:26 bar.txt
-rw-rw-r-- 1 frank frank 0 Aug 19 12:26 foo.txt
drwxrwxr-x 2 frank frank 4096 Aug 19 12:26 someFolder
$ ( ls -l . noexistABC noexistXYZ 2>&1 >&3 3>&- | grep ABC >&2 3>&-) 3>&1
.:
ls: cannot access 'noexistABC': No such file or directory
total 4
-rw-rw-r-- 1 frank frank 0 Aug 19 12:26 bar.txt
-rw-rw-r-- 1 frank frank 0 Aug 19 12:26 foo.txt
drwxrwxr-x 2 frank frank 4096 Aug 19 12:26 someFolder
これは、 bash でファイル記述子を交換する方法をモデルにした例です。 a.out の出力は、'STDXXX:' 接頭辞なしで次のようになります。
STDERR: stderr output
STDOUT: more regular
./a.out 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g'
more regular
stdErr output
上記リンクより引用:
<ブロック引用> <オール>
プロセス置換の単純な使用により、 stderr
のフィルタリングが可能になるようです stdout
とは別に :
:; ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 )
out
e:err
stderr
に注意してください stderr
に出てくる と stdout
stdout
で 、全体を別のサブシェルでラップし、ファイル o
にリダイレクトすることで確認できます と e
( ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 ) ) 1>o 2>e