我有一个 Linux 程序,它向用户提供提示,从 stdin 获取一行输入,执行操作,然后返回到提示重复(除非操作是“退出”)。我想自动向程序提供精确的输入序列,以便显示与我从键盘输入完全相同的内容。换句话说,看起来像这样:
prompt> one
prompt> two
prompt> three
我的第一个想法是创建一个input.txt
包含以下内容的文件:
one
two
three
然后运行命令:
./a.out < input.txt
这给出了正确的程序行为但显示内容显示如下,而不是与上面的第一个代码块相同:
prompt> prompt> prompt>
有什么方法可以从文件中获取输入,该文件将显示输入(在正确的点),以便显示看起来像上面的第一个代码块?
重要笔记:
我可以随意修改输入文件,但我无法修改程序。
输出也将被重定向到文件,因此获得我想要的“显示”在文件中的解决方案是很好的,但是它们可以工作。(例如,将输入文件内容直接放入输出文件的黑客攻击是可以的,但前提是各个输入最终位于相对于程序输出的正确点,因此它看起来像上面的例子)
如果解决方案比单个命令行更复杂,我可以使用 bash 脚本(或 Python 或 C)来实现解决方案(但最好使用 bash,除非用其他语言实现起来更容易)
谢谢!
tee
编辑:到目前为止我发现的使用方法......
的手册页确实tee
说,将 - 提供给 tee 会导致它再次复制到 stdout,但这只会导致所有内容的两个副本作为输入传递给./a.out
。如果我运行“tee - < input.txt”,那么它会打印以下内容:
one
two
three
one
two
three
如果我将 tee 的输出通过管道传输到 a.out,那么所有这些都将成为 a.out 的输入
于是我尝试了tee /dev/tty < input.txt
一种方法,该方法可以正确地将流的副本直接定向到终端,而只有原始副本被重定向。因此,tee /dev/tty < input.txt | ./a.out
向 a.out 提供了正确的输入,我也可以在屏幕上看到输入,但出现了两个问题:
1) 它似乎会一次性转储整个输入,而不是在从 stdin 流读取时显示。换句话说,输出如下所示:
prompt> one
two
three
prompt> prompt>
2) 如果我将 a.out 的输出重定向到文件(这是最终目标),那么发送到的流/dev/tty
仍会打印到终端,而不会出现在输出文件中。因此,该命令tee /dev/tty < input.txt | ./a.out > output.txt
将把以下内容写入 output.txt 文件:
prompt> prompt> prompt>
终端上仍会显示以下内容:
one
two
three
(如果你想想将它发送到的/dev/tty
实际含义,这有点道理......)所以我想尝试的一件事就是让 tee 将它直接发送到输出文件,就像tee -a output.txt | ./a.out >> output.txt
这样将所有内容发送到输出文件,所以它修复了上面的(2)但是(1)仍然是一个问题并且文件内容如下所示:
one
two
three
prompt> prompt> prompt>
答案1
当你这样做
./a.out < input.txt
您的 STDINa.out
是从 提供的input.txt
。通常,系统(而不是程序)会回显您的输入,因此一、二和三不是程序输出的。因此,您收到
prompt> prompt> prompt>
如果您想通过输入重定向输出,这个概念很重要。
你可以尝试
cat input.txt | tee /dev/tty | ./a.out
但由于缓冲,它可能会产生不同步的提示和输入,如下所示:
one
two
prompt>
three
prompt> prompt
并且tee
输出被写入/dev/tty
,因此不可重定向。
一个选项是使用expect
类似这样的方法:
#!/usr/bin/expect
log_user 0
spawn ./a.out
log_user 1
expect prompt
send "one\r"
expect prompt
send "two\r"
expect prompt
send "three\r"
expect prompt
生成结果:
prompt >one
prompt >two
prompt >three
的输出expect
是完全可重定向的。