275

私はこれらの3つのファイルの目的とかなり混乱しています。私の理解が正しければ、stdinはプログラムがプロセス内のタスクを実行するための要求に書き込むstdoutファイルであり、カーネルがその出力とそれを要求するプロセスが情報にアクセスするためにstderr書き込むファイルであり、すべての例外が入力されます。これらのファイルを開いて実際に発生するかどうかを確認したところ、何も示唆されていないようです。

私が知りたいのは、これらのファイルの目的が正確に何であるかということです。技術用語はほとんどありません。

4

11 に答える 11

294

標準入力-これは、プロセスが情報を取得するために読み取るファイルハンドルです。

標準出力-プロセスは従来の出力をこのファイルハンドルに書き込みます。

標準エラー-プロセスは診断出力をこのファイルハンドルに書き込みます。

それは私がそれを作ることができるのと同じくらい唖然としている:-)

もちろん、それはほとんど慣例によるものです。必要に応じて、診断情報を標準出力に書き込むことを妨げるものは何もありません。3つのファイルハンドルを完全に閉じて、I/O用に独自のファイルを開くこともできます。

プロセスが開始すると、すでにこれらのハンドルが開いているはずであり、ハンドルからの読み取りやハンドルへの書き込みを行うことができます。

デフォルトでは、それらはおそらく端末デバイス(たとえば/dev/tty)に接続されていますが、シェルを使用すると、プロセスが開始する前に、これらのハンドルと特定のファイルやデバイス(または他のプロセスへのパイプライン)の間の接続を設定できます(一部の可能な操作はかなり賢いです)。

例:

my_prog <inputfile 2>errorfile | grep XYZ

これは:

  • のプロセスを作成しますmy_prog
  • 標準入力として開きinputfileます(ファイルハンドル0)。
  • 標準エラーとして開きerrorfileます(ファイルハンドル2)。
  • の別のプロセスを作成しますgrep
  • の標準出力my_progをの標準入力に接続しgrepます。

コメントを再確認してください。

これらのファイルを/devフォルダーで開くと、実行中のプロセスの出力が表示されないのはなぜですか?

通常のファイルではないからです。UNIXはすべてをファイルシステム内のどこかにファイルとして表示しますが、それは最低レベルではそうではありません。階層内のほとんどのファイルは、/dev文字デバイスまたはブロックデバイスのいずれかであり、事実上デバイスドライバーです。サイズはありませんが、メジャーデバイス番号とマイナーデバイス番号はあります。

それらを開くと、物理ファイルではなくデバイスドライバーに接続されており、デバイスドライバーは、個別のプロセスを個別に処理する必要があることを認識できるほど賢いです。

/procLinuxファイルシステムについても同じことが言えます。これらは実際のファイルではなく、カーネル情報への厳密に制御されたゲートウェイです。

于 2010-08-02T05:34:08.517 に答える
74

stdin、、stdoutおよびstderrはファイルではなく「I/Oストリーム」であると言った方が正しいでしょう。お気づきのように、これらのエンティティはファイルシステムに存在しません。しかし、Unixの哲学は、I / Oに関する限り、「すべてがファイルである」というものです。実際には、これは、I / Oストリームがキーボード、ディスクファイル、ソケット、パイプに接続されているかどうかを気にせずに、同じライブラリ関数とインターフェイス(、、、、、など)を使用できることを意味しますprintf。 または他のI/O抽象化。scanfreadwriteselect

ほとんどのプログラムは、入力の読み取り、出力の書き込み、およびエラーのログ記録を行う必要があるため、プログラミングの便宜のために、、、およびが事前定義されていstdinますstdoutstderrこれは単なる慣例であり、オペレーティングシステムによって強制されるものではありません。

于 2010-08-02T05:36:59.550 に答える
67

上記の回答を補足するものとして、リダイレクションに関する要約を以下に示します。 リダイレクトに関するチートシート

編集:このグラフィックは完全に正しいわけではありません。

最初の例では、stdinをまったく使用せず、echoコマンドの引数として「hello」を渡します。

グラフィックには、2>&1は&>と同じ効果があることも示されていますが

ls Documents ABC > dirlist 2>&1
#does not give the same output as 
ls Documents ABC > dirlist &>

これは、&>がリダイレクトするファイルを必要とし、2>&1が単にstderrをstdoutに送信しているためです。

于 2018-04-09T14:25:41.023 に答える
27

あなたの理解は完全に逆行しているのではないかと思います。:)

「標準入力」、「標準出力」、および「標準エラー」は、カーネルの観点からではなく、プログラムの観点から考えてください。

プログラムが出力を印刷する必要がある場合、通常は「標準出力」で印刷されます。プログラムは通常、出力を標準出力に出力しprintfます。これは標準出力にのみ出力します。

プログラムがエラー情報を出力する必要がある場合(必ずしも例外ではありません。これらはプログラミング言語の構成であり、はるかに高いレベルで課せられます)、通常は「標準エラー」で出力されます。これは通常fprintf、印刷時に使用するファイルストリームを受け入れるで実行されます。ファイルストリームは、書き込み用に開かれた任意のファイル(標準出力、標準エラー、またはまたはで開かれたその他のファイル)である可能性がありfopenますfdopen

「標準入力」は、ファイルが入力を読み取る必要がある場合、またはfread、、またはを使用する場合に使用されます。fgetsgetchar

これらのファイルはいずれも、次のようにシェルから簡単にリダイレクトできます。

cat /etc/passwd > /tmp/out     # redirect cat's standard out to /tmp/foo
cat /nonexistant 2> /tmp/err   # redirect cat's standard error to /tmp/error
cat < /etc/passwd              # redirect cat's standard input to /etc/passwd

または、エンチラーダ全体:

cat < /etc/passwd > /tmp/out 2> /tmp/err

2つの重要な注意事項があります。1つは、「標準入力」、「標準出力」、および「標準エラー」は単なる慣例です。これらは非常に強力な規則ですが、このようなプログラムを実行できることは非常に素晴らしいことです。grep echo /etc/services | awk '{print $2;}' | sort各プログラムの標準出力をパイプラインの次のプログラムの標準入力に接続します。

次に、ファイルストリーム(FILE *オブジェクト)を操作するための標準のISO C関数を指定しました。カーネルレベルでは、すべてのファイル記述子(intファイルテーブルへの参照)と、およびなどのはるかに低レベルの操作ですが、そうreadwriteはありません。 ISOC関数の幸せなバッファリングを行います。私はそれをシンプルに保ち、より簡単な機能を使用することを考えましたが、同じようにあなたは代替案を知っているべきだと思いました。:)

于 2010-08-02T05:47:13.357 に答える
13

stderrエラーメッセージにのみ使用すべきだと言う人は誤解を招くと思います。

また、コマンドを実行するユーザー向けであり、データの潜在的なダウンストリームコンシューマー向けではない、情報メッセージにも使用する必要があります(つまり、複数のコマンドをチェーンするシェルパイプを実行する場合、「getting item 30 of 42424 "stdoutは消費者を混乱させるため表示されますが、それでもユーザーに表示してもらいたい場合があります。

歴史的根拠については、これを参照してください。

「すべてのプログラムが標準出力に診断を配置しました。これは、出力がファイルにリダイレクトされるときに常に問題を引き起こしていましたが、出力が疑うことを知らないプロセスに送信されると耐えられなくなりました。それにもかかわらず、標準入力の単純さに違反することを望まない-標準出力モデルでは、人々はv6を通じてこの状況を許容しました。その後まもなく、デニスリッチーは、標準エラーファイルを導入することでゴーディアンノットを切断しました。それだけでは不十分でした。パイプラインを使用すると、同時に実行されている複数のプログラムのいずれかから診断を行うことができます。診断が必要身元を明かすために」

于 2017-01-20T15:14:44.433 に答える
12

stdin

コンソールから入力を読み取ります(キーボード入力など)。scanfを使用してCで使用

scanf(<formatstring>,<pointer to storage> ...);

stdout

コンソールへの出力を生成します。printfを使用してCで使用

printf(<string>, <values to print> ...);

stderr

コンソールに「エラー」出力を生成します。fprintfを使用してCで使用

fprintf(stderr, <string>, <values to print> ...);

リダイレクション

stdinのソースをリダイレクトできます。たとえば、キーボード入力からではなく、ファイル(echo < file.txt)または別のプログラム(ps | grep <userid>)から取得できます。

stdout、stderrの宛先もリダイレクトできます。たとえば、stdoutをファイルにリダイレクトできます。ls . > ls-output.txtこの場合、出力はファイルに書き込まれますls-output.txt。 Stderrは。でリダイレクトできます2>

于 2010-08-02T05:46:52.987 に答える
5

ps -auxを使用すると、現在のプロセスが明らかになります。これらはすべて/proc/に/proc/(pid)/としてリストされています。cat/ proc /(pid)/ fd / 0を呼び出すと、の標準出力にあるものがすべて出力されます。そのプロセスだと思います。だからおそらく、

/ proc /(pid)/ fd/0-標準出力ファイル
/proc/(pid)/ fd/1-標準入力ファイル
/proc/(pid)/ fd/2-標準エラーファイル

例えばターミナルウィンドウ

しかし、これは/ bin / bashでのみうまく機能しました。他のプロセスは通常、0には何もありませんでしたが、多くのプロセスには2で書き込まれたエラーがありました。

于 2014-07-27T00:16:04.113 に答える
4

これらのファイルに関する信頼できる情報については、マニュアルページを確認し、端末でコマンドを実行してください。

$ man stdout 

しかし、簡単な答えとして、各ファイルは次の目的で使用されます。

ストリームアウトのstdout

ストリーム入力のstdin

エラーまたはログメッセージを印刷するためのstderr 。

各UNIXプログラムには、これらのストリームが1つずつあります。

于 2018-07-17T14:58:46.320 に答える
2

stderrはIOキャッシュのバッファリングを行わないため、アプリケーションが重要なメッセージ情報(一部のエラー、例外)をコンソールまたはファイルに出力する必要がある場合は、stdoutを使用して一般的なログ情報を出力する必要があります。IOキャッシュのバッファリングを使用する場合は、ファイルアプリケーションにメッセージを書き込む前に、デバッグが複雑なままになる可能性があります

于 2018-02-13T14:02:13.933 に答える
0

バッファリングが関連付けられているファイルはストリームと呼ばれ、定義されたタイプFILEへのポインタとして宣言されます。fopen()関数は、ストリームの特定の記述データを作成し、以降のすべてのトランザクションでストリームを指定するためのポインターを返します。通常、ヘッダーで宣言され、標準のオープンファイルに関連付けられた定数ポインターを持つ3つのオープンストリームがあります。プログラムの起動時に、3つのストリームが事前定義されており、明示的に開く必要はありません。標準入力(従来の入力の読み取り用)、標準出力(従来の出力の書き込み用)、および標準エラー(診断出力の書き込み用)です。開いたとき、標準エラーストリームは完全にバッファリングされていません。標準入力ストリームと標準出力ストリームは、ストリームが対話型デバイスを参照していないと判断できる場合にのみ、完全にバッファリングされます。

https://www.mkssoftware.com/docs/man5/stdio.5.asp

于 2017-09-28T13:57:35.093 に答える
0

stdinこれは、、stdoutおよびに関する長い記事stderrです:

要約する:

ストリームはファイルのように処理されます

Linuxのストリームは、他のほとんどすべてと同様に、ファイルであるかのように扱われます。ファイルからテキストを読み取ったり、ファイルにテキストを書き込んだりできます。これらのアクションは両方とも、データのストリームを含みます。したがって、データのストリームをファイルとして処理するという概念は、それほど難しいものではありません。

プロセスに関連付けられた各ファイルには、プロセスを識別するための一意の番号が割り当てられます。これはファイル記述子として知られています。ファイルに対してアクションを実行する必要がある場合は常に、ファイル記述子を使用してファイルを識別します。

これらの値は、常にstdin、stdout、およびstderrに使用されます。

0: stdin
1: stdout
2: stderr

皮肉なことに、私は異常な/非標準ストリームに関する情報を探していたので、スタックオーバーフローと上記の記事でこの質問を見つけました。だから私の検索は続けます。

于 2020-09-17T01:31:13.133 に答える