在前一个命令写入 STDOUT 时,在 STDIN 中键入另一个命令是否安全?

111*_*--- 21 shell bash stdout stdin

也许之前已经回答过这个问题,我欢迎提供另一个答案的链接......

如果我执行如下的 shell 命令(在bashshell 中):

make

然后,当输出make是通过从滚动STDOUT的的make命令,如果我输入make check并按enter之前的第一个命令执行完毕,当make命令终于完成下一个命令make check将选择权并运行。

我的问题很简单:

  1. 这样做危险吗?
  2. 这种匆忙打字是否有任何潜在的意外行为?
  3. 为什么它的工作方式如此?

Mar*_*ick 20

它的工作方式是这样的,因为 Unix 是全双工的。正如 Ritchie 在The UNIX Time-sharing System: A Retrospective 中所说:

一件事看似微不足道,但一旦习惯就会产生惊人的差异,那就是全双工终端 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 *
.
Run Code Online (Sandbox Code Playgroud)


der*_*ert 12

您看到的基本行为是输入位于缓冲区中的某个地方,直到它被读取(好吧,如果您输入足够多,最终缓冲区会填满,并且会丢失一些东西,尽管这样会输入很多内容)。make 运行的大多数东西都不会从 STDIN 读取,因此它保留在缓冲区中。

危险在于错误的命令会读取您的输入。例如,make调用决定提示您的东西,然后它可能会读取您的下一个命令作为答案。当然,这有多危险取决于命令。(他们也可能首先刷新所有输入,只是丢弃您之前的输入。)

在 Makefile 中常用的一个命令是 TeX。如果它遇到错误(并且没有给出一个永远不会提示用户的标志),它会提示你想如何继续。

更好的选择可能是运行:make && make check.


Sco*_*ott 8

  1. 嗯,半明显,您不应该运行依赖于第一个命令(make在您的示例中为 )已成功完成的第二个命令。例如,make foo Enter> ./foo Enter 可能会导致问题。您可能想尝试养成键入诸如 之类的东西的习惯make && make check,其中只有在第一个命令成功时才会执行第二个命令。
  2. 理论上有可能第一个命令(进程)可以读取第二个命令的一部分,或者以其他方式将其从终端输入缓冲区中删除。如果它吃了 的前六个字符make check,您最终将执行命令heck,该命令可能不存在于您的系统中(但可能是令人讨厌的东西)。如果第一个命令是您知道并信任的良性命令,我不会立即发现任何问题。
  3. 它如何/为什么起作用?系统缓冲键盘输入。这有点像电子邮件:您可以在短时间内向一个人发送 5 封邮件,这些邮件会放在他的收件箱中,等待他阅读。同样,只要第一个命令不是从键盘读取,您输入的命令就会等待 shell 开始读取它们。可以缓冲多少“预先输入”是有限制的,但通常是几百个字符(如果不是几千个)。

  • 对于第 1 点,假设命令是不相关的,例如 `ls` 和 `mount`。我试图了解如何处理缓冲输入。谢谢你的回答。 (2认同)