どうやら私は使用可能なすべての出力先を知りません。 stdout
(&1
)とstderr
(&2
)について知っています。ただし、両方の記述子をリダイレクトした後、時々stillがコンソールに出力されます。
考えられる最も簡単な例はGNU Parallel;使用するたびに引用の通知が表示されます。&2>1 > file
を実行しても、通知は表示されます。
同じことがemerge
にも当てはまります。emergeを実行して問題が発生すると、一部の情報がstdout
にもstdin
にも出力されません。通り抜ける。
私は主にscript
を使用してこれらの問題を解決していますが、この問題の原因は何なのかまだ疑問に思っています。
使用した構文が間違っています。
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つの問題があります。
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
が出力している場所にstdout
をリダイレクトする(つまり、コンソール出力)」を取得します。次に、「stdout
を/dev/null
にリダイレクトします。次のような状況になります。
stdout
-> /dev/null
stderr
->コンソール
だから私たちはそれを正しくします:
./testmyscript.sh >/dev/null 2>&1
そして私達は得る:
ttdada
。
次に、「stdout
を/dev/null
にリダイレクト」し、次に「stderrをstdoutが指している場所にリダイレクトします」(つまり、/dev/null
)。ばんざーい!
ただし、まだ問題があります。プログラムは/dev/tty
に出力します。現在、この種の動作を修正する方法がわからないので、script
が必要になる可能性が高いですが、この動作が頻繁に発生しないことを願っています。