프로세스가 끝날 때까지 기다리십시오
프로세스가 완료 될 때까지 Bash에 내장 기능이 있습니까?
이 wait
명령을 사용하면 하위 프로세스가 완료 될 때까지 기다릴 수 있습니다. 스크립트를 진행하기 전에 프로세스가 끝날 때까지 기다리는 방법이 있는지 알고 싶습니다.
이를 수행하는 기계적인 방법은 다음과 같지만 Bash에 내장 기능이 있는지 알고 싶습니다.
while ps -p `cat $PID_FILE` > /dev/null; do sleep 1; done
프로세스가 완료 될 때까지 기다리려면
리눅스 :
tail --pid=$pid -f /dev/null
다윈 ( $pid
파일을 열어야 함) :
lsof -p $pid +r 1 &>/dev/null
시간 초과 (초)
리눅스 :
timeout $timeout tail --pid=$pid -f /dev/null
다윈 ( $pid
파일을 열어야 함) :
lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
내장이 없습니다. kill -0
실행 가능한 솔루션을 위해 루프에서 사용하십시오 .
anywait(){
for pid in "$@"; do
while kill -0 "$pid"; do
sleep 0.5
done
done
}
또는 한 번 사용하기 쉬운 더 간단한 oneliner로 :
while kill -0 PIDS 2> /dev/null; do sleep 1; done;
여러 주석 작성자가 언급 한 것처럼 신호를 보낼 권한이없는 프로세스를 기다리려면 kill -0 $pid
통화 를 대체하기 위해 프로세스가 실행 중인지 감지하는 다른 방법을 찾으십시오 . Linux에서 test -d "/proc/$pid"
작동하면 다른 시스템에서 (사용 pgrep
가능한 경우) 또는 이와 비슷한 것을 사용해야 할 수도 있습니다 ps | grep "^$pid "
.
프로세스가 루트 (또는 다른) 소유인 경우 "kill -0"이 작동하지 않는다는 것을 알았으므로 pgrep을 사용하여 다음을 수행했습니다.
while pgrep -u root process_name > /dev/null; do sleep 1; done
이것은 아마도 좀비 프로세스를 일치시키는 단점이 있습니다.
프로세스가 존재하지 않거나 좀비 인 경우이 bash 스크립트 루프가 종료됩니다.
PID=<pid to watch>
while s=`ps -p $PID -o s=` && [[ "$s" && "$s" != 'Z' ]]; do
sleep 1
done
편집 : 위의 스크립트 는 Rockallite에 의해 아래 에 주어 졌습니다 . 감사!
에 의존하는 Linux 용 작품 아래에 내 시킴으로 빨리 대답, procfs
즉 /proc/
. 이식성에 대해 잘 모르겠습니다.
while [[ ( -d /proc/$PID ) && ( -z `grep zombie /proc/$PID/status` ) ]]; do
sleep 1
done
쉘에만 국한되지는 않지만 OS 자체에는 자식 프로세스가 아닌 프로세스 종료를 감시하는 시스템 호출이 없습니다.
FreeBSD와 Solaris는이 편리한 pwait(1)
유틸리티를 가지고 있습니다.
다른 현대 OS에도 필요한 시스템 호출 (예 : MacOS, BSD 구현 kqueue
)도 있지만 명령 줄에서 모두 사용할 수있는 것은 아닙니다.
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.
이 모든 솔루션은 Ubuntu 14.04에서 테스트되었습니다.
해결책 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
.
Solution 2 (by using top command and process name):
while [[ $(awk '$12=="process_name" {print $0}' <(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.
To see the list of processes that you wait for them to be finished, you can run:
while : ; do p=$(awk '$12=="process_name" {print $0}' <(top -n 1 -b)); [[ $b ]] || break; echo $p; sleep 1; done
Solution 3 (by using top command and process ID):
while [[ $(awk '$1=="process_id" {print $0}' <(top -n 1 -b)) ]]; do sleep 1; done
Replace process_id
with the process ID of your program.
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:
strace -qqe '' -p <PID>
Had the same issue, I solved the issue killing the process and then waiting for each process to finish using the PROC filesystem:
while [ -e /proc/${pid} ]; do sleep 0.1; done
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
).
On a system like OSX you might not have pgrep so you can try this appraoch, when looking for processes by name:
while ps axg | grep process_name$ > /dev/null; do sleep 1; done
The $
symbol at the end of the process name ensures that grep matches only process_name to the end of line in the ps output and not itself.
Blocking solution
Use the wait
in a loop, for waiting for terminate all processes:
function anywait()
{
for pid in "$@"
do
wait $pid
echo "Process $pid terminated"
done
echo 'All processes terminated'
}
This function will exits immediately, when all processes was terminated. This is the most efficient solution.
Non-blocking solution
Use the kill -0
in a loop, for waiting for terminate all processes + do anything between checks:
function anywait_w_status()
{
for pid in "$@"
do
while kill -0 "$pid"
do
echo "Process $pid still running..."
sleep 1
done
done
echo 'All processes terminated'
}
The reaction time decreased to sleep
time, because have to prevent high CPU usage.
A realistic usage:
Waiting for terminate all processes + inform user about all running PIDs.
function anywait_w_status2()
{
while true
do
alive_pids=()
for pid in "$@"
do
kill -0 "$pid" 2>/dev/null \
&& alive_pids+="$pid "
done
if [ ${#alive_pids[@]} -eq 0 ]
then
break
fi
echo "Process(es) still running... ${alive_pids[@]}"
sleep 1
done
echo 'All processes terminated'
}
Notes
These functions getting PIDs via arguments by $@
as BASH array.
참고URL : https://stackoverflow.com/questions/1058047/wait-for-a-process-to-finish
'IT story' 카테고리의 다른 글
파이썬에서 특정 위치에 문자열 추가 (0) | 2020.07.06 |
---|---|
NA를 최신 비 NA 값으로 교체 (0) | 2020.07.06 |
C #으로 JSON 파일을 작성하는 방법은 무엇입니까? (0) | 2020.07.06 |
신속한 밑줄이 필요한 이유는 무엇입니까? (0) | 2020.07.06 |
파이썬 요청으로 비동기 요청 (0) | 2020.07.06 |