対話型プロセスAが端末から入力を読み込み、時には端末から入力も読み取るプロセスBを生成すると仮定する。たとえば、Aは数字を読み、Bに制御を渡します。 Bは何でも読みます。
編集する:AとBは同時に実行されません。特定のシナリオでは、Aはsystem()
Bを呼び出すために使用されます。
Aになるように標準入力をリダイレクトすることは可能ですか?そしてBは標準入力から読みますか?
実験によると、無実
echo -e '123\nxyzzy' | A
123はAが読む必要がありますが、xyzzyはBが読む必要がありますが効果はありません。
答え1
複数のプロセスに入力を提供できます。複数のプロセスが同じパイプまたは端末からデータを読み取る場合、各バイトはプロセスの1つに移動し、どのプロセスが最初に特定のバイトを読み取るかを決定します。 1つのプロセスだけが積極的に読んでいるときに入力を受け取ります。複数のプロセスが同時にアクティブに読み込んでいる場合、どのプロセスが入力を受け取るかを予測することはできません。
あなたは紛争がありますバッファー。 Aを含むほとんどのプログラムは、入力バッファ全体(通常数百またはキロバイト)を一度に読み込み、処理を開始するまで独自のメモリに保存します。これは一度に1バイトを読むよりもはるかに高速です。しかし、この場合、AはBを呼び出す前に処理するよりも多くを読むことを意味するので、Bが起動したときにBの入力はすでにAによって消費されています。
他のソースからBを読むことができれば、これは確かに解決策です。
Aの実行方法を制御できる場合は、以下を試してください。stdbuf
GNU coreutilsから。これはライブラリ呼び出しに接続し、プロセスに一度に1バイトを読み取らせます。これはほとんどのプログラムで動作しますが、すべてではありません。静的にリンクされた実行可能ファイルでは機能せず、プログラムが標準ライブラリ(stdio)以外のバッファリング方法を使用している場合は機能しません。
… | stdbuf -i 1 A
または、通常のファイルからお読みください。 Aがパイプまたは端子から入力を読み取ると、再挿入できません。ただし、通常のファイルから読み取ると、B を呼び出す前に読み込み位置を巻き戻すことができます。read
たとえば、シェル組み込み機能の動作方法は次のとおりです。特定のプログラムAがこれを行うという保証はなく、実際には非常に一般的な動作ではありませんが、もしそうなら単純な回避策です。
これが機能しない場合、またはAの実行方法を制御できない場合は、Bが開始されるまでBのセクションが表示されないように入力時間を調整する必要があります。これを行う方法は、Bが起動したことを検出する方法によって異なります。考えられる解決策の1つは脆弱ですが、次のことを延期することです。
{ echo 123; sleep 1; echo xyzzy; } | A
これは、Aが1秒以内にBを呼び出す場合にのみ機能します。これは脆弱です。より安定した解決策は、A(またはB)で生成された出力を検出することです。これは問題です。予想される解決することを目指します。たとえば、B が次のようなプロンプトを表示する場合B>
:
#!/usr/bin/expect -f
spawn A
send "123\r"
expect "B>"
send "xyzzy\r"
答え2
これはバッファリングの問題です。プロセスAはstdioを使用してstdinからかなりの量のデータを読み取るため、Bが制御を受けると、Bの意図した部分は消えます。考えられる解決策は、次のように入力を入力することです。
python -c 'print("123" + "\n"*4093 + "xyzzy\n")' | A
期待どおりに動作します(実際のバッファサイズ - ここでは4096 - 調整が必要な場合があります)。