Cで他のファイル記述子に書き込むことはできますか?

Cで他のファイル記述子に書き込むことはできますか?

すべての標準出力をファイルにリダイレクトするには、次のようにします。

my_prog 1> out

stderrで同じことを行うには、次のようにします。

my_prog 2> err

しかし、私はシェルに別のファイル記述子があることを知っています。たとえば、上位回答この問題3番目のファイル記述子を使用すると、コマンドラインを介してデータを送信できます。

echo "Some console message" 1>&3

Cプログラムがこのファイル記述子に書き込む方法はありますか?他のプログラムから読み取らずに書き込むだけで、出力は端末に送信されますか?

ベストアンサー1

いくつかのことを明確にするために。存在する:

echo foo >&3

echo"foo\n"ファイル記述子3には書きません。echo常にファイル記述子1のstdoutに書き込みます。write()最初の引数として整数、2番目の引数で始まるメモリ領域へのポインタ、および1()の長さを使用してシステムコールを呼び出します。第三に。foo\n4foo\n

C言語ではこれを書くことができますwrite(1, "foo\n", 4)。上記のコードでは、シェルはfd 1を同じコードにリダイレクトします。ファイル説明を開くecho(システムコールを介して)呼び出す前にfd 3を開きますdup2()。したがって、機能的には同じですが、doと同じではありませんwrite(3, "foo\n", 4)。実際には(単純化)次のようになります。

if (pid = fork())
  waitpid(pid, ...);
else {
  dup2(3, 1);
  execlp("echo", "foo", 0);
} 

そしてecho作りました。write(1, "foo\n", 4)

ほとんどすべてのシェルを除外すると組み込まれているため、またはechoありません。代わりに、シェルは次のことを行います。forkexec

saved_stdout = dup(1);
dup2(3, 1);
builtin_echo("foo");
dup2(saved_stdout, 1); close(saved_stdout); /* restore stdout */

(同じプロセスでbuiltin_echo()これを行う関数はどこにありますか?)write(1, "foo\n", 4)

これを実行するコマンドについては、/の組み込みコマンドを見るwrite(3, "foo\n", 4)ことができます。kshzshprint -u3 foo

各プロセスにはファイル記述子があります。 0、1、2を除いて、規則に従ってstdin、stdout、およびstderr用に予約されています。他のfdは通常特別ではありませんが、シェル(アプリケーションの1つのタイプのみ)では、fd 0から<some-value>値が9以上の特定の場所まで(シェルの)ユーザーが使用するように予約されています。シェルはその中にスープを入れるために混ざりません。たとえば、saved_stdout = dup(1)上記の私は近似です。実際、シェルはsaved_stdout値が<some-value>

fd に 0、1、2 以外のルールが付いていないので、fd 3 では何も開くことができません。おそらく閉じているでしょう。そうでなければ、スクリプト呼び出し元はO_CLOEXCfd 3で何も開くことを期待していないため、スクリプトを開く理由がないため、スクリプトを閉じること(またはフラグを追加する)を忘れてしまった可能性があります。

fd 3に何かが開いていることがわかっている場合(通常は同じスクリプトでユーザーが事前に)、fd 3を使用できます。たとえば、次のようになります。

 {
   var=$(cmd 2>&1 >&3)
 } 3>&1

dup()ここで、fd 3はfd 1のaとして定義されます。今後これを使ってfd 1にcmd戻ります。dup()

おすすめ記事