如何优雅地挂起和恢复 `cmd1 && cmd2 && cmd3` 链?

Vi.*_*Vi. 5 bash jobs

前面的问题,似乎我无法了解&&^Z互动正确:

$ command1 && command2 && command3
Running command1 ...
Running command2 ...^Z
[1]+  Stopped
$ fg && command4
Running command3
Running command4
Run Code Online (Sandbox Code Playgroud)

,我认为它可以用来在链启动后“附加”它,似乎只是因为command3是最后一个命令;并停止它command2,例如,本应提供不同的结果(本应command3被忽略)。

如何在&&不取消其余命令的情况下优雅地暂停链?如果命令行中的进一步逻辑需要退出代码,我还希望保留退出代码。

如果我知道我可能想提前挂起链,我可以这样启动它:( command1 && command2 && command3 ),所以它应该可以优雅地挂起。Buw明明开始的时候怎么做呢?

如果命令不提供输出(与上面的示例不同),不应运行两次或乱序,那么我能想到的唯一方法是按^Z,分析停止的内容,然后手动构建fd && the_rest_of_commands,这既不方便又出错-易于。

Vol*_*gel 0

您可以挂起父 shell - 您在其中启动命令的交互式 shell:

在运行命令之前打印 PID(或稍后查找 PID,见下文):

$ echo $$
1234
Run Code Online (Sandbox Code Playgroud)

从另一个终端,您可以通过挂起交互式 shell 来停止整个命令列表 - 该列表由交互式 shell 的子进程组成:

$ kill -STOP 1234
Run Code Online (Sandbox Code Playgroud)

并继续命令列表:

$ kill -CONT 1234
Run Code Online (Sandbox Code Playgroud)


由于在运行命令列表之前不需要进行任何准备(如 ),这是用例的一个重要部分echo $$,因此当列表已在前台运行时,以下是获取要停止的 shell 的 PID 的方法。

这个想法是找到列表中任何命令的父进程的 PID:

首先,我们用来pgrep查找当前正在运行的命令的PID。找到其中任何一个的 PID 就足够了,因为一次只运行一个:

$ pgrep 'command1|command2|command3'
Run Code Online (Sandbox Code Playgroud)

如果command1等实际上不是进程的命令名称 - 即命令行的第一个单词 - 您需要添加该-f选项(并用于-a实验以查看不仅仅是PID):

$ pgrep -f 'command1|command2|command3'
Run Code Online (Sandbox Code Playgroud)

然后,我们使用ps查找命令的父PID:

$ ps -o ppid= 
Run Code Online (Sandbox Code Playgroud)

结合起来,我们得到要挂起的 shell 的 PID,如下所示:

$ pid=$(ps -o ppid= $(pgrep 'command1|command2|command3'))
Run Code Online (Sandbox Code Playgroud)

全部一起:

$ kill -STOP $(ps -o ppid= $(pgrep 'command1|command2|command3'))
$ kill -CONT $(ps -o ppid= $(pgrep 'command1|command2|command3'))
Run Code Online (Sandbox Code Playgroud)