Bash スクリプトを stderr にリダイレクトしても、stdout に出力されるのはなぜですか?

Bash スクリプトを stderr にリダイレクトしても、stdout に出力されるのはなぜですか?

Bash スクリプトがあります:

#!/bin/bash
echo this should be visible only in the stderr output but it is not 1>&2
exit 0

また、このスクリプトを開始するカスタム アプリもあります。このアプリは、stdout と stderr の両方をキャプチャします。stdout は空で、stderr には提供されたテキストが含まれます。ここまでは順調です。しかし、コンソール (物理端末) からスクリプトを開始すると、次のようになります。

./my_script.sh

ディスプレイには何も印刷されないと思っていましたが、印刷されてしまいました。 、 など、さまざまなリダイレクトの組み合わせを試しましたが>&2>/dev/stderr結果は同じでした。 また、 stdout を null にリダイレクトしようとしました1>&2 >/dev/nullが、明らかにテキストも null に送信されてしまいます。

これはどこで設定されていますか? ターミナルに stderr が表示されないようにするにはどうすればよいですか?

答え1

スクリプトが標準エラー ストリームを端末に送信しないようにするには、それを/dev/nullまたはファイルにリダイレクトする必要があります。

これを行うには、コマンド ラインでリダイレクトされた標準エラー ストリームを使用してスクリプトを呼び出すか、スクリプト自体にエラー ストリームをリダイレクトさせます。

/dev/nullコマンドラインでエラーストリームをリダイレクトするには、次のようにスクリプトを呼び出します。

./my_script 2>/dev/null

/dev/nullスクリプトが標準エラー ストリームを自動的に破棄するようにしたい場合は、スクリプト内でストリームをリダイレクトします。

#!/bin/bash

# Discard any diagnostic output, errors, and interactive prompts.
exec 2>/dev/null

echo 'This should not be visible.' >&2
echo 'This should be visible.'

/dev/nullファイルのパス名を変更して、代わりにそのファイルに診断出力を渡します。

標準出力ストリームは、標準エラー ストリームを/dev/nullファイルにリダイレクトしても影響を受けません。

通常、スクリプトは で終了してはならないことに注意してくださいexit 0

答え2

この特定のスクリプトの標準出力を破棄するには、次のようにします。

スクリプトが与えられた場合:

date
date -r /var/empty/foo

編集してグループコマンドこのようにコマンドをグループ化すると、結合されたコマンドの標準出力と標準エラー ストリームを、グループが論理的に 1 つのコマンドであるかのように処理 (リダイレクト、パイプ、破棄など) できるようになります。

例えば:

{
date
date -r /var/empty/foo
} > /dev/null

標準出力は破棄されますが、標準エラー ストリームのルーティングは変更されません。

次のスクリプト:

{
date
date -r /var/empty/foo
} > /dev/null 2>&1

標準出力を /dev/null にリダイレクトし、標準エラーを標準出力にリダイレクトして、stderr と stdout の両方を破棄します。この特定の構文は次の構文と同等です。

{
date
date -r /var/empty/foo
} > /dev/null 2>/dev/null

関連情報