等待進程完成 (Wait for a process to finish)


問題描述

等待進程完成 (Wait for a process to finish)

Is there any builtin feature in Bash to wait for a process to finish?

The wait command only allows one to wait for child processes to finish. I would like to know if there is any way to wait for any process to finish before proceeding in any script.

A mechanical way to do this is as follows but I would like to know if there is any builtin feature in Bash.

while ps -p `cat $PID_FILE` > /dev/null; do sleep 1; done

參考解法

方法 1:

To wait for any process to finish

Linux (doesn't work on Alpine, where ash doesn't support tail --pid):

tail --pid=$pid -f /dev/null

Darwin (requires that $pid has open files):

lsof -p $pid +r 1 &>/dev/null

With timeout (seconds)

Linux:

timeout $timeout tail --pid=$pid -f /dev/null

Darwin (requires that $pid has open files):

lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)

方法 2:

There's no builtin.  Use kill -0 in a loop for a workable solution:

anywait(){

    for pid in "$@"; do
        while kill -0 "$pid"; do
            sleep 0.5
        done
    done
}

Or as a simpler oneliner for easy one time usage:

while kill -0 PIDS 2> /dev/null; do sleep 1; done;

As noted by several commentators, if you want to wait for processes that you do not have the privilege to send signals to, you have find some other way to detect if the process is running to replace the kill -0 $pid call.  On Linux, test -d "/proc/$pid" works, on other systems you might have to use pgrep (if available) or something like ps | grep "^$pid ".

方法 3:

I found "kill -0" does not work if the process is owned by root (or other), so I used pgrep and came up with:

while pgrep -u root process_name > /dev/null; do sleep 1; done

This would have the disadvantage of probably matching zombie processes.

方法 4:

This bash script loop ends if the process does not exist, or it's a zombie.

PID=<pid to watch>
while s=`ps -p $PID -o s=` && [[ "$s" && "$s" != 'Z' ]]; do
    sleep 1
done

EDIT: The above script was given below  by Rockallite. Thanks!

My orignal answer below works for Linux, relying on procfs i.e. /proc/. I don't know its portability:

while [[ ( -d /proc/$PID ) && ( -z `grep zombie /proc/$PID/status` ) ]]; do
    sleep 1
done

It's not limited to shell, but OS's themselves do not have system calls to watch non-child process termination.

方法 5:

FreeBSD and Solaris have this handy pwait(1) utility, which does exactly, what you want.

I believe, other modern OSes also have the necessary system calls too (MacOS, for example, implements BSD's kqueue), but not all make it available from command-line.

(by Biswajyoti DasRauno PalosaariTeddymp3foleyteika kazuraMikhail T.)

參考文件

  1. Wait for a process to finish (CC BY-SA 3.0/4.0)

#scripting #process #bash #wait






相關問題

等待進程完成 (Wait for a process to finish)

如何使用 Inno Setup 根據註冊表項選擇在文件夾中安裝插件/文件? (How do I use Inno Setup to optionally install a plugin/file in a folder based on a registry entry?)

Python:遍歷列表但重複一些項目 (Python: Loop through list but repeat some of the items)

Skrip Perl untuk memeriksa server jarak jauh untuk proses (Perl script to check remote server for process)

持續集成中的數據庫變更管理 (Database change management in continuous integration)

如何確定html標籤是否跨多行 (How to determine if an html tag splits across multiple lines)

打開具有特定顏色和標題的 CMD (Open CMD with specific color and title)

用於搜索 XML 文檔的表單 (Form to search XML document)

反編譯 Lua 字節碼的最佳工具? (Best tool(s) for decompiling Lua bytecode?)

如何在 Blender 中通過矩陣反轉變換? (How to reverse a transformation by matrix in Blender?)

在命令行(終端)上使用 R 腳本的最佳方式是什麼? (What's the best way to use R scripts on the command line (terminal)?)

Google Sheets Script,如何創建工作表標籤的新鬆散對象 (Google Sheets Script, how to create a NEW loose object of a sheet tab)







留言討論