web-dev-qa-db-ja.com

プログラムはどのようにしてSTDOUT / STDERR以外の場所に出力しますか?それを避ける方法は?

どうやら私は使用可能なすべての出力先を知りません。 stdout&1)とstderr&2)について知っています。ただし、両方の記述子をリダイレクトした後、時々stillがコンソールに出力されます。

考えられる最も簡単な例はGNU Parallel;使用するたびに引用の通知が表示されます。&2>1 > fileを実行しても、通知は表示されます。

同じことがemergeにも当てはまります。emergeを実行して問題が発生すると、一部の情報がstdoutにもstdinにも出力されません。通り抜ける。

私は主にscriptを使用してこれらの問題を解決していますが、この問題の原因は何なのかまだ疑問に思っています。

15
MatthewRock

使用した構文が間違っています。

cmd &2>1 >file

として分割されます

cmd &
2>1 >file

この意志:

  1. リダイレクトなしでcmdをバックグラウンドジョブとして実行する
  2. 別のプロセス(コマンドなし!)では、stderr1と呼ばれるファイルにリダイレクトし、stdoutfileにリダイレクトします。

必要な構文は次のとおりです。

cmd >file 2>&1

操作の順序は重要です。この意志:

  1. stdoutfileにリダイレクト
  2. stderr&1にリダイレクトします-つまり、stdoutと同じファイルハンドル

その結果、stderrstdoutの両方がfileにリダイレクトされます。

bashでは、cmd &> fileのより単純な非標準(移植性の観点からはお勧めしません)構文でも同じことができます。

40
Stephen Harris

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/nullstderr->コンソール

だから私たちはそれを正しくします:

./testmyscript.sh >/dev/null 2>&1

そして私達は得る:

ttdada

次に、「stdout/dev/nullにリダイレクト」し、次に「stderrをstdoutが指している場所にリダイレクトします」(つまり、/dev/null)。ばんざーい!

ただし、まだ問題があります。プログラムは/dev/ttyに出力します。現在、この種の動作を修正する方法がわからないので、scriptが必要になる可能性が高いですが、この動作が頻繁に発生しないことを願っています。

11
MatthewRock