如何捕获进程 ID 并在该进程在 bash 脚本中完成时添加触发器?

How to capture a process Id and also add a trigger when that process finishes in a bash script?

我正在尝试制作一个 bash 脚本来启动一个 jar 文件并在后台执行。出于这个原因,我使用 nohup。现在我可以捕获 java 进程的 pid,但我还需要能够在进程完成时执行命令。

我就是这样开始的

nohup java -jar jarfile.jar & echo $! > conf/pid

我也从 this answer 那里知道,使用 ; 将使命令在第一个命令完成后执行。

nohup java -jar jarfile.jar; echo "done"

echo "done" 只是一个例子。我现在的问题是我不知道如何将它们结合起来。如果我先 运行 echo $! 然后 echo "done" 立即执行。如果 echo "done" 先行,那么 echo $! 将捕获 echo "done" 的 PID 而不是 jarfile 中的一个。

我知道我可以通过轮询来实现所需的功能,直到我不再看到 PID 运行ning。但我想尽可能避免这种情况。

一旦使用 nohup

启动进程,您就可以使用 bash 实用程序 wait
nohup java -jar jarfile.jar &
pid=$!     # Getting the process id of the last command executed

wait $pid  # Waits until the process mentioned by the pid is complete
echo "Done, execute the new command"

我不认为你会绕过 "polling until you don't see the pid running anymore." wait 是 bash 内置的;这就是您想要的,我确信这正是它在幕后所做的。但由于 Inian 抢在我之前,这里有一个对你友好的功能(以防你想并行获得一些东西 运行)。

alert_when_finished () {
  declare cmd="${@}";
  ${cmd} &
  declare pid="${!}";
  while [[ -d "/proc/${pid}/" ]]; do :; done; #equivalent to wait
  echo "[${pid}] Finished running: ${cmd}";
}

运行 这样的命令将产生预期的效果并抑制不需要的作业输出:

( alert_when_finished 'sleep 5' & )