私が書いたプログラムの典型的な相互作用は次のようになります。
Enter command: a_command
Completed a command
Enter command: another_command
Completed another command
私は通常、./program < input.txt
のようにプログラムを実行します。ここで、input.txt
には次のものが含まれます。
a_command
another_command
上記のように(出力だけでなく)インタラクション全体をキャプチャできるようにしたいです。どうすればbashでこれを行うことができますか?
編集:program
はバイナリ(具体的にはC++)であり、bashスクリプトではありません。ソースコードにアクセスできますが、ソースコードを変更せずにこれを実行したいと思います。
対応するプロンプトの後に入力を出力するには、プログラムがいつ入力を待機しているかを知る必要があります。実行中のプログラムを観察することから判断する方法はありません。stdinへの入力を待機しているプログラムと、他の何か(ネットワーク、ディスク、計算など)を待機しているプログラムを区別することはできません。
したがって、インタラクティブな使用のように見えるトランスクリプトを取得するプロセスは、次のようにする必要があります。
これをスクリプト化するための事実上の標準ツールは Expect です。スクリプトは次のようになります(警告:コードが機能しない、ブラウザーに直接入力):
#!/usr/bin/expect -f
set transcript_file [open "transcript" wb]
spawn myprogram
expect "Enter command:"
puts -nonewline $transcript_file $expect_out(buffer)
send "a_command\r"
puts -nonewline $transcript_file "a_command\r"
puts -nonewline $transcript_file $expect_out(buffer)
send "another_command\r"
puts -nonewline $transcript_file "another_command\r"
puts -nonewline $transcript_file $expect_out(buffer)
…
expect eof
close $transcript_file
行を追加しますset -x
プログラムファイル内。
例:
#!/bin/bash
set -x #echo on
ls $PWD
これにより、すべての変数が展開され、コマンドの出力前に完全なコマンドが出力されます。
出力:
+ ls /home/user/
file1.txt file2.txt
Setコマンドのより類似したフラグについては、Stackoverflowの この回答 を確認してください。