Как избежать неправильного процесса в bash-скрипте?

Я пишу сценарий bash, который порождает пару дочерних процессов и будет запускаться заданием cron каждый час. На самом деле он запускает команду rsync для удаленного сервера и связанное с ним соединение ssh.

Если команда или скрипт rsync отнимает слишком много времени, я бы хотел убить его и его дочерние процессы, но сначала предоставьте ему льготный период. Сценарий выполняется каждый час, но следующие 2 попытки увидят, что предыдущий экземпляр сценария запущен, и завершают работу, прежде чем начинать передачу. Третья последующая попытка уничтожит исходный, все еще работающий экземпляр, перед началом новой передачи.

Я решил управлять этим путем записи в файл PID, первый экземпляр записывает свой PID в файл, следующие две попытки записывают свой PID в файл перед выходом. Третья попытка убивает первую, а затем перезаписывает файл PID новым PID. Любое успешное завершение стирает файл PID. Чтобы убить всех детей, я решил использовать PGID исходного экземпляра сценария, который я получаю:

previous_pid=$(head -n1 "$pid_file")
previous_groupid=$(ps -hp "$previous_pid" -o pgid:1)

Затем убить его с помощью:

kill -- -"$previous_pid"

Меня беспокоит то, что Это может быть условие, когда исходный скрипт каким-то образом умер, не очистив файл PID, и этот PID используется повторно, а также многократное использование PGID, так что я закончу тем, что убил совершенно не связанный процесс. Как мне этого избежать?

2
задан 31 March 2016 в 11:55

1 ответ

Заставьте сценарий уничтожать себя. Например, имейте что-то вроде этого в начале своего сценария:

kill_myself () {
    while sleep 1
    do
        if [[ -f /tmp/kill-myself ]]
        then
            rm /tmp/kill-myself
            kill -- -$1
        fi
    done
}

kill_myself $ &

Теперь, когда время настает:

touch /tmp/kill-myself

Вы могли настроить это, так, чтобы каждый экземпляр сценария имел свой собственный фильтр, который Вы зарегистрировали бы где-нибудь. Затем Вы будете использовать тот файл для уничтожения того определенного экземпляра сценария.

<час>

Иначе: Вы могли, вероятно, использовать pgrep / pkill для более прекрасного соответствия. Они могут читать из изодромного с предварением файла, соответствия против названия команды и аргументов, и т.д.

Что-то как следующее только уничтожит процессы, которые имеют то же имя как Ваш сценарий (предполагающий, что Вы вызвали его как script-name или /path/to/script-name):

pkill -g "$previous_groupid" script-name

Это не будет работать, если Вы сделаете bash script-name. Или только уничтожить эти rsync команда, которая должна, вероятно, заставить Ваш сценарий выходить после этого:

pkill -g "$previous_groupid" rsync
3
ответ дан 31 March 2016 в 21:55
  • 1
    I' m не уверенный то, какие люди думают, неправильно с этим сообщением. It' s не действительно тот же метод как , которые отвечают , хотя он должен иметь тот же эффект. Когда выполнение нескольких команд с sudo уже, включение multiverse с add-apt-repository как показано здесь удобны, как ссылка на сообщение в блоге с большим количеством деталей (если часть информации существует несправедливость, но тогда я would' ve ожидал, что люди прокомментируют об этом, а не просто downvoting это и голосующий для удаления его). Если there' s что-то не так с этим сообщением, что я haven' t замеченный, я надеюсь, что кто-то комментирует. – Eliah Kagan 4 October 2017 в 01:20

Другие вопросы по тегам:

Похожие вопросы: