web-dev-qa-db-ja.com

'>'がgccからのエラーメッセージをリダイレクトしないのはなぜですか?

次のプログラムをnew.cに保存しました

int main() 
{ 
    a;
    return 0; 
}

エラーメッセージを返します。このメッセージをファイルに送信したいと思います。だから私は次のコマンドを使用しました

gcc new.c > temp.txt

しかし、それでも私は端末で出力を取得していました。 Ubuntu13.04を使用しています。どうすればそれを機能させることができますか?

9
Alex

gccを使用してプログラムをコンパイルすると、出力にはさまざまな種類があります。stdoutstderrです。通常、_>_はstdoutストリームをファイルに転送します(たとえば、printf("hello world\n");の結果はstdoutに送信されます)。ただし、stderrは引き続き画面に送信されます。これは、「通知が必要な例外的なもの」であると想定されているためです。

Stderrをファイルにリダイレクトする方法があります-これは次の(あまり直感的ではない)コマンドで行います:

_gcc new.c &> myFile
_

ここで、_&>_は「すべてをリダイレクトする」の「bashの省略形」です。 @CharlesDuffyが指摘したように、POSIX準拠のフォームは

_gcc new.c > myFile 2>&1
_

これは、「 'new.c'をコンパイルし、stdoutmyFileに送信します。そしてstderr(2)をstdoutと同じ場所に送信します(_&1_ = "stdoutと同じ場所")。

さまざまなリダイレクトの詳細については、 http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html および http://mywiki.wooledge)を参照してください。 org/BashFAQ/055

ちなみに、プログラム内から特にstderrに何かを送信したい場合は、次の方法で送信できます。

_fprintf(stderr, "hello world - this is urgent.\n");
_

それをプログラムに含め、プログラムを実行して「通常の」出力をファイルに送信すると、これは引き続きコンソールに表示されます。したがって、上記を実行可能ファイルurgentにコンパイルする場合は、次のように入力します。

_./urgent > /dev/null
_

コンソールでは、出力が画面に表示されます。

16
Floris

なぜなら>はstdoutのみをリダイレクトし、エラーはstderrに書き込まれます。代わりに、次のいずれかを使用する必要があります。

gcc new.c &> temp.txt ## redirect both stdout and stderr using bash or zsh only

...または...

gcc new.c >temp.txt 2>&1 ## redirect both stdout and stderr in any POSIX Shell

&>は、stdoutstderrの両方をファイルにリダイレクトするBASH拡張機能です。それ以外の場合、最も簡単なアプローチは、最初にstdout(>temp.txt)次に、次のように、stderr(FD 2)をstdout(FD 1)で既にリダイレクトされたファイルハンドルのコピーにします。2>&1

11
nims

他の人が言っているように、Linuxは2つの異なる出力ストリームを提供します。

stdout、または「標準出力」はすべての通常の出力が行われる場所です。
ファイル記述子1を使用して参照できます。

stderr、または「標準エラー」は帯域外情報の個別のストリームです。
ファイル記述子2を使用して参照できます。

なぜ2つの異なる出力ストリームなのですか?架空のコマンドのパイプラインについて考えてみましょう。

 decrypt $MY_FILE | grep "secret" | sort > secrets.txt

ここで、decryptコマンドが失敗し、エラーメッセージが生成されると想像してください。そのメッセージをstdoutに送信した場合、パイプに送信され、「秘密」という単語がない限り、メッセージは表示されません。そのため、何が悪かったのかわからないまま、空の出力ファイルになってしまいます。

ただし、パイプはstdoutのみをキャプチャするため、decryptコマンドはエラーをstderrに送信でき、そこでコンソールに表示されます。

stdoutstderrは、一緒に、または個別にリダイレクトできます。

# Send errors to "errors.txt" and output to "secrets.txt"
# The following two lines are equivalent, as ">" means "1>"
decrypt $MY_FILE 2> errors.txt > secrets.txt
decrypt $MY_FILE 2> errors.txt 1> secrets.txt

エラーをstdoutにリダイレクトして、通常の出力であるかのように処理できます。

# The operation "2>&1" means "redirect file descriptor 2 to file
# descriptor 1. So this sends all output from stderr to stdout.
# Note that the order of redirection is important.
decrypt $MY_FILE > errors.txt 2>&1 

# This may be confusing.  It will store the normal output in a file
# and send error messages to stdout, where they'll be captured by 
# the pipe and then sorted.
decrypt $MY_FILE 2>&1 > output.txt | sort

「省略形」表記を使用して、両方のstdoutとstderrを同じファイルにリダイレクトすることもできます。

decrypt $MY_FILE &> output.txt

そして最後に、>演算子は、出力ファイルに書き込む前に、まず出力ファイルを切り捨てします。代わりに、既存のファイルにデータを追加する場合は、>>演算子を使用します。

decrypt $MY_FILE 2>> more_errors.txt >> more_secrets.txt
decrypt $MY_FILE >> more_output.txt 2>&1
4
Adam Liss