2回呼び出される次のプログラムがあるとしますread()
。
#include <stdio.h>
#include <unistd.h>
#define SIZE 0x100
int main(void)
{
char buffer1[SIZE];
char buffer2[SIZE];
printf("Enter first input: \n");
fflush(stdout);
read(STDIN_FILENO, buffer1, SIZE);
printf("Enter second input: \n");
fflush(stdout);
read(STDIN_FILENO, buffer2, SIZE);
printf("\nFirst input:\n%s", buffer1);
printf("\nSecond input:\n%s", buffer2);
return 0;
}
直接呼び出すと、1
最初の入力と2
2番目の入力を受け取り、印刷できます。
First input:
1
Second input:
2
入力リダイレクトを使用するときにこれを達成するには?
最初の方法は2つの入力を使用するため、次の方法は機能しませんread
。
パイプリダイレクト:
$ { echo "1"; echo "2"; } | ./main_read
Enter first input:
Enter second input:
First input:
1
2
Second input:
区切り文字リダイレクト:
$ ./main_read << EOF
1
2
EOF
Enter first input:
Enter second input:
First input:
1
2
Second input:
ソースコードを変更することはできませんし、入力が時々SIZE
。
2人目が残りの入力を使用できるread()
ように、1人目に読書を停止するように指示する方法はありますか?read()
ベストアンサー1
これは許容可能な解決策を提供しないかもしれませんが、次の点を考慮してください。
-
ソースコードは変更できません
シェルは、実行中のプログラムの開かれたファイル記述子が指す場所を変更できず、実行中のプログラムにファイル記述子の読み取りを停止させることもできません。
競争条件を利用することに加えて、残りの選択肢のいくつかは次のとおりです。
SIZE
プログラムが常に一度にバイトを入力していることを確認してください。{ echo foo | dd bs=256 conv=sync echo bar | dd bs=256 conv=sync } 2>/dev/null | ./main_read
出力:
Enter first input: Enter second input: First input: foo Second input: bar
これは、少なくとも
SIZE
パイプバッファサイズより小さいと仮定する。expect
(またはそれに対応する)スクリプトでプログラム呼び出しをラップします。expect <<'EOT' spawn ./main_read expect "Enter first input:" send "foo\n" expect "Enter second input:" send "bar\n" expect eof EOT
または、別のコマンドの出力をパイプできるように別々に読み込みます(OSがプロセスのファイル記述子を提供すると仮定
/dev/fd/n
)。echo foo | { echo bar | expect 4<&0 <<'EOT' spawn ./main_read set chan [open "/dev/fd/3"] gets $chan line expect "Enter first input:" send "$line\r" close $chan set chan [open "/dev/fd/4"] gets $chan line expect "Enter second input:" send "$line\r" close $chan expect eof EOT } 3<&0
どちらの場合も、出力は次のようになります。
spawn ./main_read Enter first input: foo Enter second input: bar First input: foo Second input: bar
非ブロック方式でパイプを開くことができるシステム(Linuxなど)では、FIFOを使用してシェルにプログラムを読み書きすることができます。たとえば、
makefifo fifo { exec 3<>fifo ./main_read 0<&3 } | sh -c ' # read a line from the pipe # read from a file or a different pipe, write to fifo # repeat ... # echo the output from the pipe ' mysh
しかし、
expect
可能であれば、これを再創造しなければならない説得力のある理由はありません。
しかし、他の人が指摘したように、約束はありません。すべてのプログラムはread
実際にSIZE
バイトを取得します。