在执行一个命令时将命令排队

在执行一个命令时将命令排队

假设您运行的命令需要一些时间才能返回,并且希望在执行后执行另一个命令,但您没有提前计划。

我知道可以选择按Ctrl + Z然后提交fg && otherCommand。然而,这有两个主要缺陷:

  1. command1 && command2如果第一个命令是不同命令(或)的组合,则该命令不起作用,command1; command2因为第一个提交行的后续命令不会执行。
  2. 当您输入下一个命令时,第一个命令的执行将停止。对于那些令人讨厌的 30 秒命令,输入下一个命令所花费的时间即使不是全部,也占了剩余执行时间的很大一部分。

我还知道您可以在执行一个命令时输入下一个命令,然后点击Enter提交它。然而,这也有两个重大缺陷:

  1. 如果您首先执行的命令从 读取,则它将不起作用stdin
  2. 如果您首先执行的命令产生输出,您将看不到您输入的内容。

是否有一种快速方法可以在执行一个命令时对更多命令进行排队,可能涉及使用特殊的终端仿真器或多个终端?

答案1

Ctrl+Z并立即运行bg。这会导致当前命令继续在后台运行。然后您可以使用在当前时间之后fg && otherCommand进行安排。otherCommand

为了使这更容易,我在 shell 中配置了Ctrl+ ,当我在空命令行上按 + 时运行。看Zbg在 zsh 中,我怎样才能更快地否认前台进程?如何将命令行应用程序直接发送到后台?;我还没有检查现代版本的 bash 是否可以轻松执行相同的操作。

答案2

您可以创建一个命名管道(这需要完成一次):

mkfifo ~/myfifo

然后从终端(我们称之为终端 A)你可以说:

exec 10< ~/myfifo

要将管道的读取端分配给文件描述符 10,您可以使用 2 以上的任何其他数字(因此,如果另一个命令需要标准输入、输出和错误,则标准输入、输出和错误仍然可用)。

然后从另一个终端(我们称之为终端 B)你可以说:

cat - > ~/myfifo

完成与终端 A 的连接,然后返回提示符。该命令将从标准输入输入的内容写入管道。然后您可以在终端 A 中输入以下内容:

while read -u10 -r LINE; do eval "$LINE"; done

因此它将执行您在终端 B 中键入的命令。该read命令将从文件描述符 10 读取行并使用 执行它evaleval允许您运行 shell 命令,例如导出变量。

只要终端 A 打开,您就可以使用 Ctrl+C 中断循环,以便您可以再次输入命令,然后您可以重新启动循环以开始运行剩余的排队命令。

exec 和 while 命令可以放入 shell 脚本中,这样 fg && yourscript如果您一开始忘记了,可以使用 Ctrl-Z 来激活管道模式。

答案3

您最有可能想要:

wait $pid

如果您不在同一个 shell 中运行,则无法使用内置命令,并且需要解决方法。查看讨论这里

答案4

编辑:我误解了这个问题,但是下面的技术可能对人们在 bash 脚本中运行命令时仍然有用(所以他们有单个 PID)

这就是我使用的(在Linux上),当command1正在打印有用的输出并且我只想在完成后在另一个shell中启动另一个进程(也就是说,我不想后台command1):

tail --pid=$command1_pid -f /dev/null; command2

$command1_pid您正在等待完成的进程的 PID 在哪里

(我想我最初在这里找到它:https://stackoverflow.com/a/41613532/1676393。请参阅此处以获取有用的其他详细信息。例如适用于 Darwin (macOS) 的版本)


一步步:

  • Ctrl使用+停止命令 1Z
  • run ps,然后查找command1对应的进程,并找到其PID
  • 然后通过键入 重新启动 command1 进程fg,并在新 shell 中运行上述命令

这样,当 command1 在旧 shell 中完成时,command2 将在新 shell 中启动。

相关内容