web-dev-qa-db-ja.com

一部のLinuxプログラムの出力がSTDOUTにもSTDERRにも送信されないのはなぜですか?

一部のLinuxプログラムの出力がSTDOUTにもSTDERRにも送信されないのはなぜですか?

実際、使用する「ストリーム」に関係なく、すべてのプログラム出力を確実にキャプチャする方法を知りたいです。私が抱えている問題は、一部のプログラムが出力をキャプチャできないように見えることです。

例は「time」コマンドです。

time sleep 1 2>&1 > /dev/null

real        0m1.003s
user        0m0.000s
sys         0m0.000s

または

time sleep 1 &> /dev/null

real        0m1.003s
user        0m0.000s
sys         0m0.000s

なぜ両方の時間に出力が表示されるのですか?私はそれがすべて / dev/null にパイプされることを期待していました。

どの出力ストリームが使用されていますか?それをファイルにパイプするにはどうすればよいですか?

この問題を回避する1つの方法は、_ Bash スクリプトを作成することです。たとえば、combine.shこのコマンドを含む:

$@ 2>&1

次に、「時間」の出力を正しい方法でキャプチャできます。

combine.sh time sleep 1 &> /dev/null

(出力は表示されません-正しい)

別の結合スクリプトを使用せずに私が望むものを達成する方法はありますか?

21
Will Sheppard

この質問は BashFAQ/032 で扱われます。あなたの例では、あなたは:

{ time sleep 1; } 2> /dev/null

理由

time sleep 1 2>/dev/null

その構文では、timeコマンドsleep 1 2>/dev/null(はい、コマンドsleep 1 withstderr/dev/null)にリダイレクトされます。組み込みのtimeは、これを実際に可能にするためにそのように機能します。

bashbuiltinは実際にこれを行うことができます。なぜなら...まあ、それはビルトインだからです。このような動作は、通常/usr/binにある外部コマンドtimeでは不可能です。確かに:

$ /usr/bin/time sleep 1 2>/dev/null
$

今、あなたの質問への答え

一部のLinuxプログラムの出力がSTDOUTにもSTDERRにも送信されないのはなぜですか?

is:それは、出力がstdoutまたはstderrに送られます。

お役に立てれば!

38
gniourf_gniourf

timeビルトインに関する特定の質問に回答しましたが、stdoutにもstderrにも書き込まないコマンドがいくつかあります。典型的な例は、Unixコマンド crypt です。引数のないcryptは、標準入力stdinを暗号化し、それを標準出力stdoutに書き込みます。 getpass() を使用してユーザーにパスワードの入力を求めます。これにより、デフォルトで_/dev/tty_にプロンプ​​トが出力されます。 _/dev/tty_は現在の端末デバイスです。 _/dev/tty_への書き込みには、現在の端末への書き込みと同じ効果があります(存在する場合は、isatty()を参照してください)。

cryptstdoutに書き込めない理由は、暗号化された出力をstdoutに書き込むためです。また、ユーザーがstderrstdoutをリ​​ダイレクトした場合でもプロンプトが表示されるように、stderrに書き込むのではなく_/dev/tty_にプロンプ​​トを表示することをお勧めします。 (同じ理由で、cryptは、暗号化するデータの読み取りに使用されているため、stdinからパスワードを読み取ることができません。)

14
Alok

_time sleep 1 > /dev/null 2>&1_#「スリープ」の出力をリダイレクトしてnullにします。次に、「time」はリダイレクトなしで独自の出力を書き込みます。 「time (sleep 1 > /dev/null 2>&1)」のようなものです。

_(time sleep 1) > /dev/null 2>&1_#「timesleep 1」を実行し、その出力をnullにリダイレクトします。

[] s

0
Márcio