stdinとstdoutをファイルにリダイレクトする

stdinとstdoutをファイルにリダイレクトする

そのため、ユーザー入力を受け取り、入力に応じてテキストを出力するプログラムがあります。

EDIT2:ファイルからCプログラムの入力を提供し、出力を別のファイルにリダイレクトするC実行可能ファイルを実行するスクリプトを作成したいと思います。ただし、入力用に出力が印刷されるたびに、基本的に入力と出力を一緒に結合/マージして入力も印刷したいと思います。そのため、入力をファイルに 1 行ずつ入力し、各入力の出力をファイルに印刷し、この操作を続けます。私はプログラムを再実行したくないので、入力ファイルの終わりに到達するか、スクリプトから終了信号を送信するまでプログラムを実行し続けたいと思います。 (クラスのスコアスクリプトを作成しようとしています。生徒がプログラムを送信したら、私はスクリプトを実行してプログラムに入力を提供しますが、入力+出力を一緒に追跡して各出力をより簡単に追跡できるようにしたいと思います。入力)残りスクリプトを直接生成する方法を見つけることができましたが、入力+出力を結合するのを妨げました。

Edit3:プログラムが何を出力するのかわからないので、期待がうまくいかないと思います。私はそれが何を受け入れるべきかを知っています。たとえば、ある生徒に「文字を入力してください」というプログラムがあり、もう一方の生徒に「文字を入力してください -」と言うと、そのプログラムで何が起こるのかわかりません。

(注:さまざまな形式のさまざまな実行可能ファイルがありますが、すべて同じ量の入力を要求する必要があります。)

たとえば、実行可能ファイルの1つは次のとおりです。

"Enter a number: " (Wait for user input)
"Give another: "  (Wait for user input
"Total: " (Output based on input)
"Do you want to run again? "(Wait for user input)

編集:私のスクリプトの主な目的は、ファイルから1行ずつ入力を受け取るプログラムを実行することです。たとえば、このプログラムでは、ファイルを標準入力として「入力」したいのですが、標準出力とマージされた標準入力も追跡したいと思います。

だから私は./a.out<input>outputが出力されることを知っています。

Enter a number: 
Give another:  
Total:  15
Do you want to run again? 

ただし、含める入力が欠落しているため、出力ファイルを見て、出力に基づいて入力が何であるかを知ることができます。入力は、7 8 N または 5 10 N または同様のものである可能性があるためです。

答え1

私が正しく理解している場合は、a.outstdinからデータを読み取った時点とそのデータが同じログファイルに転送され書き込まれた時点を検出し、対話式に実行したときにechostdoutがリダイレクトされ、ローカル端末をエミュレートするようにしますか?

これにより、ソリューション(bash構文)は次のようになります。

mkfifo strace.fifo
{
  while read -d, trace; do
    if [[ $trace = *"read(0" ]]; then
      IFS= read -rn1 answer <&3 || break
      answer=${answer:-$'\n'}
      printf %s "$answer" >&2
      printf %s "$answer"
    fi
  done < strace.fifo 3< answers.txt |
    strace -o strace.fifo -e read ./a.out
} > log 2>&1

アイデアはstrace(Linuxを使用すると仮定すると)readシステムコールを追跡し、ファイル記述子0が存在するたびreadanswers.txt

編集する:プログラムがstdioなどを使用している場合。出力が通常のファイルにリダイレクトされ、もはや端末でない場合は、出力されるすべてのプロンプトがバッファリングされ、プログラムが終了したときにのみフラッシュされます。

回避策は以下を使用することです。にstdbuf変更してください。これは、端末であるかのようにstdoutでラインバッファリングを実行するようにアプリケーションに指示します(動的に接続されたアプリケーションであり、バッファリングがstdioによって引き起こされると仮定します)。しかし、まだやっていないことは、stdinからstdioを読むときにstdoutをフラッシュすることです。これはstdin / stdoutが端末の場合に通常行われます。たとえば、改行文字で終わらないプロンプトは、改行文字が明示的または最終的に作成されるまで表示されません。したがって、最良の方法はバッファリングを完全に無効にすることです。./a.outstdbuf -oL ./a.outfflushstdbuf -o0

a.outプロセスやスレッドを分岐できる場合は、この-fオプションをstrace

アプリケーションがselect実際に非ブロックI / Oをpoll実行している場合は、readデータをすばやく送信することもできます。

コメントで述べたように。expectユーザー対話をシミュレートするためのツールです。擬似端末を使用するため、入力エコーが自動的に発生し、何も発生しません。バッファリングされた出力質問。代わりに付属のスクリプトを使用して疑似端末をラップstdbufできます。この場合、標準出力でプロンプトを再現するために、デバイスの読み取りと応答の送信の間にわずかな遅延を追加することができます。unbuffera.outexpect

答え2

これに使用されますscript。それがまさにその目的です。

script /tmp/logfile -c 'your command here'

たとえば、

>> script /tmp/log -c 'read -p "Value: " value; echo "value=$value"'
Script started, file is /tmp/log
Value: foo
value=foo
Script done, file is /tmp/log

>> cat /tmp/log
Script started on Wed 01 May 2013 01:16:34 PM EDT
Value: foo
value=foo

Script done on Wed 01 May 2013 01:16:35 PM EDT

関連情報