明らかに利用可能なすべての出力先がわかりません。私はstdout
(&1
)とstderr
(&2
)を知っています。しかし、両方の記述子をリダイレクトした後、時々まだ私のコンソールからいくつかの出力を得る!
私が考えることができる最も簡単な例はGNU Parallelです。使用するたびに参照通知が表示されます。これにより、&2>1 > file
通知が引き続き表示されます。
同じことが当てはまりますemerge
:私が実行して何か間違っている場合、いくつかのメッセージは印刷されません。stdout
なぜならstdin
私はそれらをリダイレクトしているので、まだ渡されているからです。
を使用してこれらの問題をほとんど解決しましたが、script
まだ問題の原因が何であるかを知りたいです。
答え1
使用中の構文が正しくありません。
cmd &2>1 >file
に分割されます
cmd &
2>1 >file
これは次のことを行います。
cmd
リダイレクトなしでバックグラウンドジョブとして実行- 別のプロセス(コマンドなし!)から
stderr
文字通り呼び出されたファイルにリダイレクト1
し、次にstdout
リダイレクトします。file
必要な構文は次のとおりです。
cmd >file 2>&1
作業順序が重要です。これは次のことを行います。
stdout
リダイレクトfile
- リダイレクト -
stderr
つまり&1
、同じファイルハンドルstdout
その結果stderr
と両方stdout
にリダイレクトされますfile
。
では、bash
より単純な非標準構文(移植性のために推奨されていない)もcmd &> file
同じことを行います。
答え2
2つの質問があります。
1つ目は順序が重要で、2つ目は/dev/tty
。
出力をキャプチャするサンプルスクリプトとしてこのスクリプトを使用します。
test.sh
:
#!/bin/bash
echo dada
echo edada 1>&2
echo ttdada >/dev/tty
それでは、コマンドの出力を見てみましょう。
./testmyscript.sh 2>&1 >/dev/null
:
edada
ttdada
評価順序は左から右なので、まず「出力が出力される位置(つまりコンソール出力)stderr
にリダイレクト」を取得します。次に「redirect to」をstdout
取得します。私たちは次のような状況で終わります。stdout
/dev/null
stdout
-> /dev/null
stderr
->コンソール
したがって、正しい結果が得られます。
./testmyscript.sh >/dev/null 2>&1
私達は次を得ました:
ttdada
。
今、私たちは「redirect stdout
to /dev/null
」を実行し、次に「stdoutが指す場所にstderrをリダイレクトします」とします/dev/null
。歓声!
しかし、まだ問題があります。プログラムがで印刷されます/dev/tty
。この動作を修正する方法がわからないので、修正する必要があるかもしれませんが、script
この動作が頻繁に発生しないことを願っています。