Я пишу сценарий 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, так что я закончу тем, что убил совершенно не связанный процесс. Как мне этого избежать?
Заставьте сценарий уничтожать себя. Например, имейте что-то вроде этого в начале своего сценария:
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
sudo
уже, включениеmultiverse
сadd-apt-repository
как показано здесь удобны, как ссылка на сообщение в блоге с большим количеством деталей (если часть информации существует несправедливость, но тогда я would' ve ожидал, что люди прокомментируют об этом, а не просто downvoting это и голосующий для удаления его). Если there' s что-то не так с этим сообщением, что я haven' t замеченный, я надеюсь, что кто-то комментирует. – Eliah Kagan 4 October 2017 в 01:20