コマンドまたはシェルスクリプトの出力がstdoutまたはstderrであるかどうかを確認する方法


32

コマンドまたはシェルスクリプトを実行すると、出力が得られます。このコマンドまたはシェルスクリプトの内部を知らずに、出力がstderrまたはからであるかどうかをどのように判断しstdoutますか?

たとえば、

$ ls -ld /
drwxrwxr-t  35 root  admin  1258 Dec 11 19:16 /

ls -ld /test
ls: /test: No such file or directory

最初のコマンドが印刷されstdout、2番目のコマンドが印刷されたことを確認するにはどうすればよいstderrですか?


1
ここで解決しようとしている問題は何ですか?
ケンスター

3
誰かがそれを尋ねることを恐れていました。本当に好奇心が強く、リダイレクトの理解を深めることを望んでいる人はいません。
KM。

7
stderredシェル環境LD_PRELOADに入れstdoutstderr、異なる色にすることができます。これに関連する質問を次に示します。
アンコ

回答:


18

出力が既に印刷されていると通知する方法はありません。この場合、stdoutstderrは両方とも端末に接続されているため、どのストリームに書き込まれたかに関する情報は、端末にテキストが表示されるまでにすでに失われています。これらは、端末に到達する前にプログラムによって結合されました。

あなたは何ができるか、上記のような場合には、使用してコマンドを実行することであろうstdoutstderr別の場所にリダイレクトし、何が起こるかを参照してください。それとも一回、二回、それを実行stdoutにリダイレクト/dev/nullし、一回stderrにリダイレクト/dev/nullし、テキストでこれらのケースの結果のどれが現れてご覧ください。

あなたはリダイレクトできstdout/dev/nullタックにより>/dev/null、コマンドラインの最後に、あなたはリダイレクトすることができますstderr/dev/null追加することによって2>/dev/null


9

を使用してstdoutをリダイレクトし> file、を使用してstderrをリダイレクトでき2> fileます。最新のシェルの多くはコマンドへのリダイレクトをサポートしているため、sedどの出力がどのストリームからのものかを強調するために使用できます。

$ ls 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
1: unity_support_test.0
1: vmwareDnD

$ ls foo 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
2: ls: cannot access foo: No such file or directory

非常に素晴らしい!接頭辞ではなく色で行を強調表示できると便利です。
-dotancohen

3
@dotancohen:1つできます!例えば、(echo "this is stdout"; echo "this is stderr" >&2) > >(sed 's/.*/\x1b[32m&\x1b[0m/') 2> >(sed 's/.*/\x1b[31m&\x1b[0m/')
PM 2Ring

stdoutとstderrからの出力が混在している場合は、最初にstdoutが出力され、次にstderrが出力されることに注意してください。
nyuszika7h

5

annotate-outputDebianのからスクリプトをdevscripts使用すると、選択的にこれを行うことができます:

$ annotate-output ls -ld /test
14:54:22 -: Started ls -ld /test
14:54:22 E: ls: cannot access /test: No such file or directory
14:54:22 -: Finished with exitcode 2

2番目の列は、stdoutおよびstderr with Oおよびwith をEそれぞれ示しています。

いくつかの注意事項がありますが、主なものは他の回答に記載されているとおりです。事実の後、これを行うことはできません。シェルも端末も、任意のプログラムがファイル記述子をどのように使用するかを認識していませんが、シェルはそれらを最初に設定する責任があります。

このメソッドはfifoを使用します。fifoへの書き込みはttyへの書き込みとは異なる動作をする可能性があり、2つの異なるfifoへの書き込みは明らかに異なります(潜在的なタイミング/インターリーブの問題)。また、インタラクティブな使用には適していません。たとえばannotate-output bash、素晴らしい計画ではありませんが、他の多くの目的には役立ちます。stdin / stdout / stderrの色付けに関する関連質問への回答には、スクリプトとシェル関数の多くの例があります。最も堅牢なのは、stderrdに書き込まれたデータを(ほとんどの)プログラムのランタイム変更を使用して変更するstderrdです。

Ankoがリンクしているこの質問には、その関連テーマに関する良い答えがあります:stdout / stderr出力の色付け: STDERRとSTDOUTを異なる色で印刷するようにシェルを構成できますか?


1
ループをbash使用し、stdoutまたはstderrの各行に対してwhile read1つのdateコマンドを実行するスクリプトであるため、cmd > >(ts '%T O:') 2> >(ts '%T E:')同等のものよりもはるかに効率が低下することに注意してください。
ステファンシャゼラス

1

他の答えとは別に、指すことは本質的です/proc/$PID/fd(ただし、質問には答えません)。

$ cat > /dev/null 2> /tmp/blablah &
[1] 3073

[1]+  Stopped                 cat > /dev/null 2> /tmp/blablah
$ ls -l /proc/3073/fd
total 0
lrwx------ 1 kampde kampde 64 Feb 24 11:43 0 -> /dev/pts/33
l-wx------ 1 kampde kampde 64 Feb 24 11:43 1 -> /dev/null
l-wx------ 1 kampde kampde 64 Feb 24 11:43 2 -> /tmp/blablah

ご覧のとおり、ここではプロセスに対して開かれたファイル記述子を見ることができます。0STDIN1あるSTDOUT2されますSTDERR。STDOUTまたはSTDERRがリダイレクトされていない場合は/dev/pts/33、端末を指すため(少なくともこの例では)表示されます。

/proc/$PID実行中のプロセスに対してのみ存在します。この場合、cat引数なしで使用しているため、を閉じるまで終了しませんSTDIN。また、バックグラウンドで実行したため、この例のためにすぐにPIDを取得します。


0

あなたが何を求めているのかは明確ではありませんが、これは役立つかもしれません

ls -ld /
echo $?    # Exit status 0 returned because command executed successfully.

ls -ld /test
echo $?    # Non-zero exit status returned -- command failed to execute

ソース

終了コードが0の場合、単にコマンドが正しく実行されたこと(stdout)を意味します。ここでは、終了コードが0(stderr)と異なる場合の意味を見つけることができます。


とても興味深い!終了ステータスをリダイレクトに接続したことはないでしょう。ゼロは暗示しstdout、ゼロ以外は暗示しstderrますか?
KM。

7
@KM。いいえ。私はそれが強く相関すると言いますが、プログラムstderrが良いエラーコードに書き込んstdoutで返すこと、または悪いエラーコードに書き込んで返すことを止めるものは何もありません。実際、試してみてくださいfind /root-ルートとして実行していないと仮定すると、2行が出力されるはずです-「/ root」が出力されstdout、「find:/ root:Permission denied」が出力されstderrます。また、findは不正な戻りコードを返します。
godlygeek

opの問題は、どちらが標準出力か標準エラーかをどのように判断するかということです。
it_is_a_literature

0

通常、STDERRでは、メッセージの前にコロンが付いたプログラム名が付けられます。

例:

rpm -zq some_utils 
rpm: -zq: unknown option

rpm -ql some_utils 
package some_utils is not installed

-1

エラー出力をキャプチャしてテストするには:

ls -l test 2>errors
if [ -s errors ]; then echo "There were errors:" && cat errors; fi
rm errors
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.