也许之前已经回答过这个问题,我欢迎提供另一个答案的链接......
如果我执行一个 shell 命令(在bash
shell 中),如下所示:
make
然后,当命令的输出从命令的make
前面滚动时,如果我在第一个命令完成执行之前键入并按下,则当命令最终完成时,下一个命令将立即启动并运行。STDOUT
make
make check
entermake
make check
我的问题很简单:
- 这样做危险吗?
- 这种匆忙打字是否会带来任何潜在的意外行为?
- 为什么会这样?
答案1
它之所以这样工作是因为 Unix 是全双工的。正如里奇所说UNIX 分时系统:回顾:
一件看似微不足道的事情,一旦习惯了就会产生惊人的差异,那就是全双工终端 I/O 和预读。尽管程序通常以行而不是单个字符与用户进行通信,但全双工终端 I/O 意味着用户可以随时键入,即使系统正在回输,而不必担心丢失或乱码。通过预读,无需等待每一行的响应。一个优秀的打字员在输入文档时会因为在开始每一行之前必须暂停而感到非常沮丧;对于任何知道自己想说什么的人来说,如果信息必须一点一点地输入而不是全速输入,那么任何反应迟缓都会在心理上被放大。
[引用结束]
话虽如此,有些现代程序会耗尽或丢弃任何预先输入的内容。ssh
和apt-get
这是两个例子。如果您在它们运行时提前输入,您可能会发现输入的第一部分已经消失。可以想象,这可能是一个问题。
ssh remotehost do something that takes 20 seconds
mail bob
Dan has retired. Feel free to save any important files and then do
# ssh exits here, discarding the previous 2 lines
rm -fr *
.
答案2
您看到的基本行为是输入位于缓冲区中的某个地方,直到被读取为止(好吧,如果您输入足够多的内容,最终缓冲区会填满,并且会丢失一些东西,这就是很多虽然打字)。大多数由 make 运行的东西不会从 STDIN 读取,因此它保留在缓冲区中。
危险在于错误的命令读取您的输入。例如,make
调用决定提示您的内容,然后它可能会读取您的下一个命令作为答案。当然,这有多危险取决于命令。 (他们也可能首先刷新所有输入,只是丢弃您之前的输入。)
Makefile 中常用的命令 TeX 可以实现此目的。如果遇到错误(并且没有给出从不提示用户的标志),它将提示您如何继续。
更好的选择可能是运行:make && make check
。
答案3
- 好吧,半明显的是,您不应该运行依赖于第一个命令(
make
在您的示例中)已成功完成的第二个命令。例如,make foo
Enter>./foo
Enter 可能会导致问题。您可能想尝试养成输入类似 的习惯make && make check
,其中只有第一个命令成功时才会执行第二个命令。 - 理论上,第一个命令(进程)可以读取第二个命令的一部分,或者以其他方式将其从终端输入缓冲区中删除。如果它吃了 的前六个字符
make check
,您最终将执行该命令heck
,该命令可能不存在于您的系统上(但可能是令人讨厌的东西)。如果第一个命令是您了解并信任的良性命令,我不会立即发现任何问题。 - 它如何/为什么起作用?系统缓冲键盘输入。这有点像电子邮件:您可以在短时间内向某人发送五封邮件,这些邮件将放在他的收件箱中,等待他阅读。同样,只要第一个命令不是从键盘读取,您键入的命令就会等待 shell 读取它们。可以缓冲多少“预先输入”是有限制的,但通常是几百个字符(如果不是几千个的话)。