programing

프로세스가 완료될 때까지 기다립니다.

abcjava 2023. 4. 21. 20:06
반응형

프로세스가 완료될 때까지 기다립니다.

Bash에 프로세스가 완료될 때까지 대기하는 빌트인 기능이 있습니까?

wait명령어를 사용하면 하위 프로세스가 완료될 때까지 대기할 수 있습니다.어떤 프로세스가 완료될 때까지 기다렸다가 어떤 스크립트로 진행할 수 있는 방법이 있는지 알고 싶습니다.

기계적인 방법은 다음과 같습니다만, Bash에 내장 기능이 있는지 알고 싶습니다.

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

프로세스가 완료될 때까지 기다리려면

가 Linux를Alpine에서는 하지 않습니다)tail --pid

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

(Darwin (:$pid열려 있는 파일이 있습니다.

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

타임아웃 포함(초)

Linux:

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

(Darwin (:$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
}

또는 한 번에 쉽게 사용할 수 있는 간단한 온라인 라이너로 다음과 같이 하십시오.

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에 의해 아래에 제공되었습니다.감사합니다!

에 의존합니다.procfs ㅇㅇㅇ./proc/이치노

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

셸에만 국한된 것이 아니라 OS 자체에는 자녀 이외의 프로세스 종료를 감시하는 시스템 호출이 없습니다.

및 한 FreeB가 .SD(Solaris)를 선택합니다.pwait(1)유틸리티, 즉 원하는 대로 사용할 수 있습니다.

의 OS에도들어 MacOS는하고 있습니다).kqueue모든 것을 명령줄에서 사용할 수 있는 것은 아닙니다.

bash manpage에서

   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.

네, 정답은 - 아니요, 내장된 툴은 없습니다.

" " " /proc/sys/kernel/yama/ptrace_scope로로 합니다.0 , 을할 수 있습니다.strace「」.가 되어, 대기할 수 .또한 스위치를 사용하여 무음 상태로 만들 수 있으므로 실제로 수동적으로 대기할 수 있습니다.

strace -qqe '' -p <PID>

이러한 솔루션은 모두 Ubuntu 14.04에서 테스트되고 있습니다.

솔루션 1(ps 명령어 사용):Pierz의 답변을 종합하자면, 저는 다음과 같이 제안합니다.

while ps axg | grep -vw grep | grep -w process_name > /dev/null; do sleep 1; done

「」는,grep -vw grepgrep process_name은 grep의 grep입니다.할 수 .ps axg.

솔루션 2(top 명령 및 프로세스 이름 사용):

while [[ $(awk '$12=="process_name" {print $0}' <(top -n 1 -b)) ]]; do sleep 1; done

process_name 기재되어 합니다.top -n 1 -b이치노

완료될 때까지 기다리는 프로세스 목록을 보려면 다음을 수행합니다.

while : ; do p=$(awk '$12=="process_name" {print $0}' <(top -n 1 -b)); [[ $b ]] || break; echo $p; sleep 1; done

솔루션 3(top 명령 및 프로세스 ID 사용):

while [[ $(awk '$1=="process_id" {print $0}' <(top -n 1 -b)) ]]; do sleep 1; done

process_id아이디

블로킹 솔루션

하다를 사용하세요.wait모든 프로세스가 종료될 때까지 대기합니다.

function anywait()
{

    for pid in "$@"
    do
        wait $pid
        echo "Process $pid terminated"
    done
    echo 'All processes terminated'
}

이 기능은 모든 프로세스가 종료되면 즉시 종료됩니다.이것이 가장 효율적인 해결책입니다.

논블로킹 솔루션

하다를 사용하세요.kill -0루프에서 모든 프로세스의 종료를 대기하기 위해 + 체크 사이의 모든 작업을 수행합니다.

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'
}

.sleepCPU 사용률이 높아지지 않도록 해야 하기 때문입니다.

현실적인 사용법:

모든 프로세스가 종료될 때까지 대기하고 실행 중인 모든 PID에 대해 사용자에게 알립니다.

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'
}

메모들

PID를 할 때 PID를 취득합니다.$@BASH 어레이로 지정합니다.

같은 문제가 발생하여 프로세스를 중지하고 각 프로세스가 PROC 파일 시스템을 사용할 때까지 기다리는 문제를 해결했습니다.

while [ -e /proc/${pid} ]; do sleep 0.1; done

프로세스가 완료될 때까지 대기하는 빌트인 기능은 없습니다.

.kill -0볼 수 ps 를 하고 있는 ,ps를 참조해 주세요.

프로세스를 종료하고 완료될 때까지 기다려야 하는 경우 (프로세스 이름에 기반) 및 (pid 파일에 기반)를 사용하여 프로세스를 종료할 수 있습니다.

「」에하는 모든 를 종료합니다.someproc다음과 같이 합니다.

killall someproc --wait             # wait forever until matching processes die
timeout 10s killall someproc --wait # timeout after 10 seconds

(과)는.--waitkill(syslog pid'syslog)

pid를 합니다./var/run/someproc.pid, 시그널 「」의SIGINT, 와 함께,, , , , , , ,리리리리리리리리리리리 , , , , , , 。SIGKILL20달러

start-stop-daemon --stop --signal INT --retry 20 --pidfile /var/run/someproc.pid

프로세스가 종료될 때 닫히는 일부 파일을 모니터링하려면 inotifywait를 사용합니다.예(Linux의 경우):

yourproc >logfile.log & disown
inotifywait -q -e close logfile.log

-e는 대기할 이벤트를 지정합니다.-q는 종료 시에만 최소 출력을 의미합니다.이 경우 다음과 같습니다.

logfile.log CLOSE_WRITE,CLOSE

단일 wait 명령을 사용하여 여러 프로세스를 대기할 수 있습니다.

yourproc1 >logfile1.log & disown
yourproc2 >logfile2.log & disown
yourproc3 >logfile3.log & disown
inotifywait -q -e close logfile1.log logfile2.log logfile3.log

inotifywait 출력 문자열은 종료된 프로세스를 알려줍니다.이것은, /proc/에 있는 것이 아니고, 「실제」파일에서만 동작합니다.

Palosaari의 Rauno Palosaari용 【루 ra】Timeout in Seconds Darwin GNU 「GNU」 「GNU」 「UNIX」 OS 를 하고 있지 않은 UNIX 에 대한 입니다.tail)Darwin UNIX와 에 따라 과 같이 실패할 수

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

UNIX에서는, 「유닉스」lsof 「」+r 1m%s( 저슈슈슈슈슈슈 。

lsof: can't read kernel name list.

m%s는 출력 포맷 사양입니다.심플한 포스트 프로세서는 필요 없습니다.예를 들어 다음 명령어는 PID 5959에서 최대 5초간 대기합니다.

lsof -p 5959 +r 1 | awk '/^=/ { if (T++ >= 5) { exit 1 } }'

예에서는, 5하기 전에 는, 「PID 5959」입니다.${?}0 않은 경우아니라면${?}15월 15일

...에 .라는 것을 분명히 언급할 가치가 있을지도 모른다.+r 1 , . . . . . . . .1는 폴링 간격(초단위)이므로 상황에 맞게 변경할 수 있습니다.

OSX와 같은 시스템에서는 pgrep이 없을 수 있으므로 프로세스 이름을 검색할 때 다음 평가를 사용해 보십시오.

while ps axg | grep process_name$ > /dev/null; do sleep 1; done

$프로세스 이름 끝에 있는 기호를 사용하면 grep이 ps 출력의 행 끝에 process_name만 일치하고 그 자체는 일치하지 않습니다.

언급URL : https://stackoverflow.com/questions/1058047/wait-for-a-process-to-finish

반응형