web-dev-qa-db-ja.com

cのstderrからの読み取り

これは私が書いた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

回答ありがとうございます。

stderrは、読み取りではなく書き込みを目的としています。 dupstdinlicateである場合もあります(たとえば、3つのin/out/errがすべて端末に接続されている場合)。別のプログラムのstderrを読み取るには、そのプログラムのstderrを別のプログラムのstdinにリダイレクトします。

例えばstdoutをファイルに転送し、stderr./myprogramsstdinに転送します。

command 2>&1 >a_file | ./myprogram
1
ctrl-alt-delor

bashzshのようなシェル(ただし、単純なPOSIX shではありません)を使用すると、firstprogram 2> >(second program)を介して1つのプログラムの標準エラーを別のプログラムの標準入力にリダイレクトできます。

例:

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

ほとんどのリファレンスブックとドキュメントが常に標準エラーを出力として参照していることを考えると、多くの人にとってこれは驚きです。実際、通常は read + write で開いています。あなたのプログラムは非常にファイル記述子2から読み取ることができます

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

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

親プロセスでリダイレクトが使用されていないログインセッションのプログラムの場合、ファイル記述子2(標準エラー)は通常、ファイル記述子0(標準入力)の複製です。どちらも同じ基本的な file description を参照します。これは通常、ログインセッションのターミナルです(ttymonによって開かれ、複製されます。または、古いシステムではgettyセッションの開始時)。

ファイル記述子2から読み取る場合、ファイル記述子0から読み取った場合と同じ入力が得られます。

ところで、ファイル記述子2からの読み取りは、パスワード入力などの目的で頻繁に行われていました。 /dev/ttyデバイスが導入される前、1977年頃。ファイル記述子2から読み取る理由は、ファイル記述子0が別の場所にリダイレクトされたときに元の端末から入力を取得するためでした(パイプラインの途中の場合のように、例えば)。

/dev/ttyは長い間利用可能でしたが、40年以上もの間、POSIXではファイル記述子2を読み取り用に開く必要があります。

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

別のプログラムのファイル記述子2の出力から読み取ることは別のことです。標準出力を標準エラーとマージすることなく、それ自体を簡単に実行することはできません。これには通常、一連の3>&1 1>&2 2>&3などのスワップが含まれます。いくつかのシェルは、呼び出しによって出力ファイル記述子2のパイプを許可します

prog1 2| prog2

しかし、そのようなシェルはまれであり、 your プログラムが必要とするものではありません。

プログラムに入力を送信する

ファイル記述子2から読み取るプログラムで、ターミナルからではなく other から読み取る場合は、もちろんそのファイル記述子をリダイレクトします。通常の input リダイレクト構文(シェルの<演算子)をできます使用できますが、プログラムのライブラリ、またはあなたが他の場所で書いた他のコードでさえ、彼らがこのファイル記述子に書き込むことができるという仮定があります。

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

./myprogram 2<>filename

シェルリダイレクト以外にも、ファイル記述子の操作を可能にする多くのツールがあります。例:Laurent Bercotのチェーン読み込み redirfd ツール(execlineに付属)を使用すると、このリダイレクトは仮説に似たものになります。

redirfd -u 2 filename ./myprogram

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

./myprogram 2<<< "here string"
0
schily