这两天在做 CSAPP 的练习题,做到第二章的拆弹题。具体的题目就不说了。目标是找到隐藏在文件里的多个密码,一行一行输入。
现在我已经找到了两个密码。那么现在就出现了一个问题:
每次程序都要求我顺序输入每个密码,那么我接下来在测试第三个密码的时候,每次都要重新输入前两个密码,才能进入第三个密码的阶段。那么我每次都要复制粘贴一遍?这也太蠢了。
所以很自然地我想到了重定向。把前两个密码输入到文件 ans.txt
里面,然后运行 bomb
文件的时候使用重定向:
./bomb < ans.txt
看起来很完美。但是是有问题的。这么做的话,文件重定向不止会将文件内容输入进去,在最后它还会输入一个 EOF
,导致整个输入结束。所以这么运行出来,结果是这样的:
./bomb < ans.txt
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
That's number 2. Keep going!
Error: Premature EOF on stdin
前两个密码被解开了。但是没有向我询问第三个密码,而是直接报错退出了。
所以现在出现一个问题:
有没有什么办法,可以让我重定向输入到一个文件的同时,在文件输入结束后,不要输入 EOF
,而是将控制权再转回到标准输入呢?
这个问题其实我之前也遇到过,用途其实还是挺多的。比如说如果你用一些 REPL,比如 ipython
,你有的时候就会有这样的需求:我要先让它运行一个文件的内容,然后接着让我自己输入命令。 不过当然 ipython
是提供了运行文件的命令,所以这个需求可以绕开。但是如果你想流程化 gdb
,pdb
之类的工具,就只能借助于重定向了。
好了不废话了,答案其实也很简单。今天早上洗脸的时候突然想到的,想到之后觉得我之前怎么那么笨:
cat ans.txt - | ./bomb
不直接用文件重定向,而是用 cat
开一个管道。cat
的作用是拼接多个文件,但是其实它也可以将标准输入作为一个文件拼接,只需要在它的参数表里面用 -
代表标准输入。所以 cat ans.txt -
这个命令可以将 ans.txt
与标准输入拼接为一个新文件。然后我们将 cat
的输出重定向到 ./bomb
。
完美。