回答:
を使用してプログラムをコンパイルするとgcc
、出力の種類が異なります:to stdout
とstderr
。通常、>
指示するstdout
(例えば、結果をファイルにストリームprintf("hello world\n");
に送られますstdout
)。ただし、stderr
「通知が必要な例外的なもの」であると想定されるため、画面には引き続きが送信されます。
stderrをファイルにリダイレクトする方法があります。これを行うには、次の(あまり直感的ではない)コマンドを使用します。
gcc new.c &> myFile
ここで&>
、「すべてリダイレクト」の「bash省略形」です。@CharlesDuffyによって指摘されたように、POSIX準拠のフォームは
gcc new.c > myFile 2>&1
これは、「new.cをコンパイルしてに送信stdout
しmyFile
ます。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
コンソールで、出力が画面に表示されます。
>myFile 2>&1
)とbash拡張(&>
)を実際に導入する必要があります。
ので>
リダイレクトのみ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
&>
両方stdout
とstderr
ファイルにリダイレクトするBASH拡張機能です。それ以外の場合、最も簡単な方法は、最初にstdout(>temp.txt
)をリダイレクトし、次にstderr(FD 2)をstdout(FD 1)の既にリダイレクトされたファイルハンドルのコピーにすることです2>&1
。
他の人が言ったように、linuxは2つの異なる出力ストリームを提供します:
stdoutまたは「標準出力」は、すべての通常の出力が行われる場所です。
ファイル記述子を使用して参照できます1
。
stderrまたは「標準エラー」は、帯域外情報の個別のストリームです。
ファイル記述子を使用して参照できます2
。
なぜ2つの異なる出力ストリームがあるのですか?架空のコマンドのパイプラインを考えます。
decrypt $MY_FILE | grep "secret" | sort > secrets.txt
decrypt
コマンドが失敗し、エラーメッセージが生成されることを想像してください。そのメッセージをstdout
に送信した場合、パイプに送信されます。「秘密」という単語がなければ、メッセージは表示されません。したがって、何が問題だったかわからないまま、空の出力ファイルが作成されます。
ただし、パイプはをキャプチャするだけなstdout
ので、decrypt
コマンドはエラーをstderr
に送信し、コンソールに表示されます。
stdout
およびstderr
は、一緒にまたは個別にリダイレクトできます。
# 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
$FOO
)の使用は、バグの一般的な原因であり、例でそれを示すことはそれほど大きくありません。(2)すべて大文字の変数名を使用することが、環境変数と組み込み変数(慣習では大文字)とローカル変数(慣習では小文字)の間で名前空間が競合する主な理由です。(3)>>
ファイルを一度開いて複数のコマンドで使用するためにファイル記述子を開いたままにするのではなく、繰り返し使用する(コマンドで使用されるたびにファイルを開く)ように人々に勧めると、コードの効率が悪くなります。
exec 4>secrets; echo "this is a secret" >&4; echo "this is another secret" >&4
command₁
>
output_file
;
command₂
>>
the_same_output_file
(
command₁
;
command₂
) >
output_file
{
command₁
;
command₂
; } >
output_file
{
;
}