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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:17:54  来源:igfitidea点击:

Wait for a process to finish

bashscriptingprocesswait

提问by Biswajyoti Das

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

Bash 中是否有任何内置功能可以等待进程完成?

The waitcommand 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 $pidhas 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 $pidhas 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 -0in 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 $pidcall. 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 procfsi.e. /proc/. I don't know its portability:

我下面的原始答案适用于 Linux,依赖于procfsie /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 grepensures 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_namewith 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_idwith 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_scopeto 0, it is possible to use the straceprogram. 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 -0to 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 文件系统完成的问题:

##代码##