事先不知道我会想要这样做,是否可以等待一项作业完成并自动开始执行另一项作业?
例如,我跳入 tmux 会话并执行sudo apt update && sudo apt upgrade
.然后我创建一个新窗格并开始做一些事情,却发现我的系统上需要另一个我目前没有的包。我必须等待我的更新/升级过程完成,但它正在缓慢地进行,我不想等待它,特别是因为我可以在它进行时做其他事情,而不是等待它。
我可以很好地^Z
完成bg
这项工作,但我的问题是,有没有办法在该工作完成后插入一项工作,以便我可以&& sudo apt install tree
举例?
编辑:我认为这个问题与链接的问题和答案不同,因为job1 && job2
^Z
fg; echo "done"
将在完成echo "done"
后执行job1
:job2
显然被丢弃。解决方法是在job1
和之间使用分号job2
,但这对我来说不是一个很好的解决方案。
答案1
一般来说,没有比给出的更好的解决方案了基本作业控制:停止作业,将作业添加到堆栈中,以及“fg”,但正如您所指出的,使用 with 时会失败&&
(因为放置在后台的命令以非零状态代码“退出”),并且无论如何复合命令并不总是具有所需的效果(当前运行的命令放置在后台,并且立即运行以下命令)。
对于这个特定的用例,有一个解决方案 - 您可以使用 Diomidis Spinellis 的lockf.py
apt
创建等待当前命令完成的命令队列:
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
答案4
如果您养成了总是进行更新/升级的习惯,
( sudo apt update && sudo apt upgrade )
然后作业控制正确地暂停子进程,允许您键入
fg ; echo "Example new command"