ファイル記述子2が読み取りおよび書き込み用に開かれています。

ファイル記述子2が読み取りおよび書き込み用に開かれています。

これはstderrで読み取るために書いたCプログラムです。

#include <uninstd.h>
#include <stdio.h>

int main(void) {
 char buff[3];
 read(2, buff, sizeof(buff));
 printf("%s", buff");
 return 0;
}

私の質問はstderrを送信する方法です。ほとんどの検索は bash リダイレクトとして表示されます。

command 2> file

ただし、これはstderrをファイルに送信します。

私のプログラムにどのように渡すことができますか?ドットのように、

command 2 "somthing here" ./myprogram

答えてくれてありがとう。

答え1

ほとんどの参考書と文書は常に標準エラーを出力として提供し、実際には通常既に読み取り+書き込み用に開いています。。あなたのプログラムはとても気に入っていますできるファイル記述子2から読み込みます。

(注:この回答は実際のファイル記述子番号を使用します。Cフローstderrプログラムはこれを変更することができ、Cストリームの役割について話すときに混乱を加重するので、実際にこれらのファイル記述子に対応する必要はありません。あなたのプログラムはread()。 )

ファイル記述子2が読み取りおよび書き込み用に開かれています。

親プロセスでリダイレクトを使用しないログインセッションのプログラムの場合、ファイル記述子2(標準エラー)は通常、ファイル記述子0(標準入力)のコピーです。彼らはすべて同じ基本を参照しています。ファイル説明、これは通常セッションがログインする端末です(ttymon以前のシステムでgettyセッションの開始時に開かれ、コピーされます)。

ファイル記述子 2 から読み取る場合、ファイル記述子 0 から読み取るのと同じ入力を取得します。

/dev/tty注:1977年頃にこのデバイスを導入する前に、ファイル記述子2で読むことはパスワード入力などの目的でよく使用されました。ファイル記述子2から読み取る理由は、ファイル記述子0が別の場所(パイプの途中など)にリダイレクトされたときに元の端末から入力を取得するためです。

/dev/ttyPOSIXは40年以上の長い歴史を持っていますが、まだファイルディスクリプタ2を読むために開いている必要があります。

あなたのプログラムが何もしないこと

ファイル記述子2から別のプログラムの出力を読むことは別の問題です。君は簡単にできないそれ自体を通して、標準出力と標準エラーをマージしません。通常、シリーズ3>&1 1>&2 2>&3または同様の交換が含まれます。一部のシェルは以下を呼び出して、出力ファイル記述子2へのパイプを許可します。

prog1 2| prog2

しかし、そのような殻はまれです。あなたのそれにもかかわらず、プログラムはこれを要求します。

プログラムに入力を送信

プログラムがファイル記述子 2 から読み取るようにするには、以下を読み取ることができます。その他もちろん、端末よりも対応するファイル記述子をリダイレクトできます。あなたできる一般的な使用入力するリダイレクト構文(<シェルの演算子)ですが、プログラムのライブラリとは別の場所で作成した他のコードもこのファイル記述子に書き込むことができるとします。

シェルを使用すると、<>リダイレクト演算子を使用して読み書きするためにファイルを明示的に開くことができます。これは、プログラムのファイル記述子2をリダイレクトするときに使用します。

./myprogram 2<>filename

シェルリダイレクトに加えて、ファイル記述子を操作するための多くのツールがあります。例: Laurent Bercot のチェーンロードredirfdexeclineに付属のツールは、このリダイレクトがあなたの仮説に似ているようです。

redirfd -u 2 filename ./myprogram

Bourne AgainやZシェル(Almquistシェルではない)などのシェル構文も、ファイル記述子2の「ここにドキュメント」と「ここに文字列」を提供します。ファイル記述子2が開いていることに注意してください。読み取り専用この場合、これらの殻を介して。

./myprogram 2<<< "here string"

答え2

stderr読み取り用ではなく書き込み用です。時にはdup重複することがありますstdin(たとえば、3つの入力/出力/エラーがすべて端末に接続されている場合)。他のプログラムのstderrを読むには、そのプログラムのstderrを別のプログラムのstdinにリダイレクトできます。

stdoutたとえば、ファイルをポイントしてstderrから。./myprogramsstdin

command 2>&1 >a_file | ./myprogram

答え3

bashzsh通常のPOSIX以外のandなどのシェルを使用すると、あるshプログラムの標準エラーを別のプログラムの標準入力にリダイレクトすることでこれを行うことができますfirstprogram 2> >(second program)

例:

$ perl -E 'say "perl stdout"; warn "perl stderr\n"' 2> >(awk '{print "awk", $0}')
perl stdout
awk perl stderr

答え4

入力リダイレクトを設定するようにシェルに指示するには、またはを使用してstderrファイルディスクリプタ番号の前に次を付けます。<<<<<<

./myprog 2< somefile.txt

または

./myprog 2<<< "some text"

しかし、stderrそのようにリダイレクトすると、プログラムは出力つまり、プログラム(またはプログラムが使用するライブラリ)が印刷しようとする可能性のあるエラーメッセージは表示されず、さらにプログラムがそのメッセージを作成しようとするとエラーが発生することを意味します。

現在実行中のタスクを実行する他の方法があるかどうか再考することもできます。少なくともプログラムにいくつかの入力を提供したいという考えでは、例えばfd 3を使うことを考えてみましょう。

関連情報