Дождитесь окончания процесса - PullRequest
121 голосов
/ 29 июня 2009

Есть ли в Bash встроенная функция для ожидания завершения процесса?

Команда wait позволяет только дождаться завершения дочерних процессов. Я хотел бы знать, есть ли какой-либо способ дождаться завершения какого-либо процесса, прежде чем приступить к какому-либо сценарию.

Механический способ сделать это следующим образом, но я хотел бы знать, есть ли какая-либо встроенная функция в Bash.

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

Ответы [ 13 ]

1 голос
/ 14 июня 2017

Возникла та же проблема, я решил проблему, убив процесс и затем дождавшись завершения каждого процесса с использованием файловой системы PROC:

while [ -e /proc/${pid} ]; do sleep 0.1; done
0 голосов
/ 08 сентября 2015

Блокирующий раствор

Используйте 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'
}

Время реакции уменьшилось до sleep времени, потому что нужно предотвратить высокую загрузку ЦП.

Реалистичное использование:

Ожидание завершения всех процессов + информирование пользователя о всех работающих 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 с помощью аргументов $@ как массив BASH.

0 голосов
/ 03 февраля 2015

В такой системе, как OSX, у вас может не быть pgrep, поэтому вы можете попробовать это приложение при поиске процессов по имени:

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

Символ $ в конце имени процесса гарантирует, что grep сопоставляет только имя_процесса с концом строки в выводе ps, а не с собой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...