bash 等待一个进程完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1058047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait for a process to finish
提问by Biswajyoti Das
Is there any builtin feature in Bash to wait for a process to finish?
Bash 中是否有任何内置功能可以等待进程完成?
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.
该wait
命令只允许等待子进程完成。我想知道在继续执行任何脚本之前是否有任何方法可以等待任何进程完成。
A mechanical way to do this is as follows but I would like to know if there is any builtin feature in Bash.
执行此操作的机械方法如下,但我想知道 Bash 中是否有任何内置功能。
while ps -p `cat $PID_FILE` > /dev/null; do sleep 1; done
回答by Rauno Palosaari
To wait for any process to finish
等待任何进程完成
Linux:
Linux:
tail --pid=$pid -f /dev/null
Darwin (requires that $pid
has open files):
达尔文(要求$pid
有打开的文件):
lsof -p $pid +r 1 &>/dev/null
With timeout (seconds)
超时(秒)
Linux:
Linux:
timeout $timeout tail --pid=$pid -f /dev/null
Darwin (requires that $pid
has open files):
达尔文(要求$pid
有打开的文件):
lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
回答by Teddy
There's no builtin. Use kill -0
in a loop for a workable solution:
没有内置。kill -0
在循环中使用以获得可行的解决方案:
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:
或者作为一个更简单的 oneliner,方便一次性使用:
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 "
.
正如几位评论员所指出的,如果您想等待您没有权限向其发送信号的进程,您可以找到其他方法来检测该进程是否正在运行以替换kill -0 $pid
调用。在 Linux 上test -d "/proc/$pid"
有效,在其他系统上您可能必须使用pgrep
(如果可用)或类似ps | grep "^$pid "
.
回答by mp3foley
I found "kill -0" does not work if the process is owned by root (or other), so I used pgrep and came up with:
我发现如果进程由 root(或其他人)拥有,“kill -0”不起作用,所以我使用 pgrep 并想出了:
while pgrep -u root process_name > /dev/null; do sleep 1; done
This would have the disadvantage of probably matching zombie processes.
这将具有可能匹配僵尸进程的缺点。
回答by teika kazura
This bash script loop ends if the process does not exist, or it's a zombie.
如果进程不存在,或者它是一个僵尸进程,那么这个 bash 脚本循环就会结束。
PID=<pid to watch>
while s=`ps -p $PID -o s=` && [[ "$s" && "$s" != 'Z' ]]; do
sleep 1
done
EDIT: The above script was given belowby Rockallite. Thanks!
编辑:上面的脚本是由Rockallite在下面给出的。谢谢!
My orignal answer below works for Linux, relying on procfs
i.e. /proc/
. I don't know its portability:
我下面的原始答案适用于 Linux,依赖于procfs
ie /proc/
。我不知道它的便携性:
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.
它不仅限于 shell,而且操作系统本身没有系统调用来观察非子进程终止。
回答by Mikhail T.
FreeBSD and Solaris have this handy pwait(1)
utility, which does exactly, what you want.
FreeBSD 和 Solaris 有这个方便的pwait(1)
实用程序,它完全符合您的要求。
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.
我相信,其他现代操作系统也有必要的系统调用(例如,MacOS 实现了 BSD 的kqueue
),但并非所有操作系统都可以从命令行获得它。
回答by Charlweed
From the bash manpage
从 bash 联机帮助页
wait [n ...]
Wait for each specified process and return its termination status
Each n may be a process ID or a job specification; if a
job spec is given, all processes in that job's pipeline are
waited for. If n is not given, all currently active child processes
are waited for, and the return status is zero. If n
specifies a non-existent process or job, the return status is
127. Otherwise, the return status is the exit status of the
last process or job waited for.
回答by Saeid BK
All these solutions are tested in Ubuntu 14.04:
所有这些解决方案都在 Ubuntu 14.04 中进行了测试:
Solution 1 (by using ps command):Just to add up to Pierz answer, I would suggest:
解决方案 1(通过使用 ps 命令):为了补充 Pierz 的答案,我建议:
while ps axg | grep -vw grep | grep -w process_name > /dev/null; do sleep 1; done
In this case, grep -vw grep
ensures that grep matches only process_name and not grep itself. It has the advantage of supporting the cases where the process_name is not at the end of a line at ps axg
.
在这种情况下,grep -vw grep
确保 grep 仅匹配 process_name 而不是 grep 本身。它的优点是支持 process_name 不在行尾的情况ps axg
。
Solution 2 (by using top command and process name):
解决方案 2(通过使用 top 命令和进程名称):
while [[ $(awk '=="process_name" {print while : ; do p=$(awk '=="process_name" {print while [[ $(awk '=="process_id" {print strace -qqe '' -p <PID>
}' <(top -n 1 -b)) ]]; do sleep 1; done
}' <(top -n 1 -b)); [[ $b ]] || break; echo $p; sleep 1; done
}' <(top -n 1 -b)) ]]; do sleep 1; done
Replace process_name
with the process name that appears in top -n 1 -b
. Please keep the quotation marks.
替换process_name
为 中出现的进程名称top -n 1 -b
。请保留引号。
To see the list of processes that you wait for them to be finished, you can run:
要查看等待它们完成的进程列表,您可以运行:
while [ -e /proc/${pid} ]; do sleep 0.1; done
Solution 3 (by using top command and process ID):
解决方案 3(通过使用 top 命令和进程 ID):
##代码##Replace process_id
with the process ID of your program.
替换process_id
为您程序的进程 ID。
回答by emu
Okay, so it seems the answer is -- no, there is no built in tool.
好吧,看来答案是——不,没有内置工具。
After setting /proc/sys/kernel/yama/ptrace_scope
to 0
, it is possible to use the strace
program. Further switches can be used to make it silent, so that it really waits passively:
设置/proc/sys/kernel/yama/ptrace_scope
为 后0
,即可使用该strace
程序。可以使用进一步的开关使其静默,以便它真正被动地等待:
回答by TheBonsai
There is no builtin feature to wait for any process to finish.
没有等待任何进程完成的内置功能。
You could send kill -0
to any PID found, so you don't get puzzled by zombies and stuff that will still be visible in ps
(while still retrieving the PID list using ps
).
您可以发送kill -0
到任何找到的 PID,这样您就不会被僵尸和仍然可见的东西所迷惑ps
(同时仍然使用 检索 PID 列表ps
)。
回答by littlebridge
Had the same issue, I solved the issue killing the process and then waiting for each process to finish using the PROC filesystem:
遇到了同样的问题,我解决了杀死进程然后等待每个进程使用 PROC 文件系统完成的问题:
##代码##