命令“等待作业完成然后开始另一项作业”?

命令“等待作业完成然后开始另一项作业”?

事先不知道我会想要这样做,是否可以等待一项作业完成并自动开始执行另一项作业?

例如,我跳入 tmux 会话并执行sudo apt update && sudo apt upgrade.然后我创建一个新窗格并开始做一些事情,却发现我的系统上需要另一个我目前没有的包。我必须等待我的更新/升级过程完成,但它正在缓慢地进行,我不想等待它,特别是因为我可以在它进行时做其他事情,而不是等待它。

我可以很好地^Z完成bg这项工作,但我的问题是,有没有办法在该工作完成后插入一项工作,以便我可以&& sudo apt install tree举例?

编辑:我认为这个问题与链接的问题和答案不同,因为job1 && job2 ^Z fg; echo "done"将在完成echo "done"后执行job1job2显然被丢弃。解决方法是在job1和之间使用分号job2,但这对我来说不是一个很好的解决方案。

答案1

一般来说,没有比给出的更好的解决方案了基本作业控制:停止作业,将作业添加到堆栈中,以及“fg”,但正如您所指出的,使用 with 时会失败&&(因为放置在后台的命令以非零状态代码“退出”),并且无论如何复合命令并不总是具有所需的效果(当前运行的命令放置在后台,并且立即运行以下命令)。

对于这个特定的用例,有一个解决方案 - 您可以使用 Diomidis Spinellis 的lockf.pyapt创建等待当前命令完成的命令队列:

lockf /var/lib/apt/lock apt install tree

这可以推广到任何可以以可预测的方式从外部观察其完成情况的命令。

队列是无序的,如果您运行,可能会导致问题

sudo apt update && sudo apt upgrade

并在运行时对安装进行排队apt update,您可能最终会apt install运行 after apt update,并apt upgrade因无法获得锁定而失败。

答案2

使用flock(1)Linux 中的实用程序(或lockf.py其他操作系统中的脚本)回答,这在这方面是类似的)不保证“排队”命令将按照它们提交的顺序运行。

$ sh -c 'for i in 1 2 3 4 5 6 7 8 9; do sleep .1; flock / sh -c "echo $i; sleep .3" & done; wait'
1
2
3
5
4
...

创建作业队列的一个愚蠢的“解决方案”可能是这样的:

$ (echo > jobq; tail -f jobq | sh) &
[2] 6641
$ echo echo 1 >> jobq
1
$ echo echo 2 >> jobq
$ 2
etc

答案3

您应该使用任务假脱机程序(tsp不是ts) 执行多个apt命令:

tsp apt command 1 -y

然后使用-d选项将第二个apt命令添加到队列列表中:

tsp -d apt command 2 -y

用于tsp检查列表的统计信息。

曼茶匙:

ts默认情况下将运行每个用户的 UNIX 任务队列。用户可以将命令添加到队列中,随时观察该队列,并查看任务结果(实际上是标准输出和退出错误)。

-d

仅当之前的命令顺利完成时才运行该命令(错误级别 = 0)。排队的新任务取决于上一个命令的结果。如果任务没有运行,则认为进一步依赖失败。

答案4

如果您养成了总是进行更新/升级的习惯,

( sudo apt update && sudo apt upgrade )

然后作业控制正确地暂停子进程,允许您键入

fg ; echo "Example new command"

相关内容