1

我想在另一个后台 Bash 作业中引用一个后台 Bash 作业。那可能吗?

例如,假设我开始了一项后台工作:

$ long_running_process &
[1] 12345

现在我希望在该工作完成时发生一些事情,所以我可以使用wait

$ wait %1 && thing_to_happen_after_long_running_process_finishes

但是,这会阻塞,我希望我的终端回来做其他事情,但Ctrl+Z什么也不做。

首先尝试在后台启动它会失败:

$ { wait %1 && thing_to_happen_after_long_running_process_finishes; } &
[2] 12346
-bash: line 3: wait: %1: no such job
$ jobs
[1]-  Running     long_running_process &
[2]+  Exit 127    { wait %1 && thing_to_happen_after_long_running process_finishes; }

有没有办法wait在另一个后台工作中引用一个工作?

我使用 GNU Bash 4.1.2(1)-release 看到了这种行为。

4

2 回答 2

3

一个 shell 只能wait在它自己的孩子上。由于后台作业会创建一个新的 shell,wait因此该 shell 中的 a 只能等待其自己的子代,而不是其父代的子代(即,后台等待分叉的 shell)。对于您想要的,您需要提前计划:

long_running_process && thing_to_happen_after &

有一种选择:

long_running_process &
LRP_PID=$!

{ while kill -0 $LRP_PID 2> /dev/null; do sleep 1; done; thing_to_happen_after; } &

这将设置一个循环,尝试每秒 ping 一次您的后台进程。处理完成后,kill将失败,并继续进行后处理程序。它有轻微的风险,即您的进程将退出并且另一个进程将在检查之间获得相同的进程 ID,在这种情况下,它kill会变得混乱并认为您的进程仍在运行,而实际上它是新的进程。但这是非常轻微的风险,实际上如果thing_to_happen_after延迟一段时间直到没有 ID 的进程之前可能还可以$LRP_PID

于 2013-08-06T16:26:55.187 回答
0

尝试这样的事情:

  x2=$(long_running_process && thing_to_happen_after_long_running_process_finishes ) &
于 2013-08-06T18:30:26.933 回答