假设您运行的命令需要一些时间才能返回,并且希望在执行后执行另一个命令,但您没有提前计划。
我知道可以选择按Ctrl + Z然后提交fg && otherCommand
。然而,这有两个主要缺陷:
command1 && command2
如果第一个命令是不同命令(或)的组合,则该命令不起作用,command1; command2
因为第一个提交行的后续命令不会执行。- 当您输入下一个命令时,第一个命令的执行将停止。对于那些令人讨厌的 30 秒命令,输入下一个命令所花费的时间即使不是全部,也占了剩余执行时间的很大一部分。
我还知道您可以在执行一个命令时输入下一个命令,然后点击Enter提交它。然而,这也有两个重大缺陷:
- 如果您首先执行的命令从 读取,则它将不起作用
stdin
。 - 如果您首先执行的命令产生输出,您将看不到您输入的内容。
是否有一种快速方法可以在执行一个命令时对更多命令进行排队,可能涉及使用特殊的终端仿真器或多个终端?
答案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 读取行并使用 执行它eval
。eval
允许您运行 shell 命令,例如导出变量。
只要终端 A 打开,您就可以使用 Ctrl+C 中断循环,以便您可以再次输入命令,然后您可以重新启动循环以开始运行剩余的排队命令。
exec 和 while 命令可以放入 shell 脚本中,这样 fg && yourscript
如果您一开始忘记了,可以使用 Ctrl-Z 来激活管道模式。
答案3
答案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 中启动。