Váš příklad i přijatá odpověď jsou příliš komplikované, proč ne pouze použijte timeout
protože to je přesně jeho případ použití? timeout
příkaz má dokonce vestavěnou volbu (-k
) odeslat SIGKILL
po odeslání počátečního signálu k ukončení příkazu (SIGTERM
ve výchozím nastavení), pokud příkaz stále běží po odeslání počátečního signálu (viz man timeout
).
Pokud skript nutně nevyžaduje wait
a obnovit tok řízení po čekání je to prostě záležitost
timeout -k 60s 60s app1 &
timeout -k 60s 60s app2 &
# [...]
Pokud však ano, je to stejně snadné uložením timeout
Místo toho PID:
pids=()
timeout -k 60s 60s app1 &
pids+=($!)
timeout -k 60s 60s app2 &
pids+=($!)
wait "${pids[@]}"
# [...]
Např.
$ cat t.sh
#!/bin/bash
echo "$(date +%H:%M:%S): start"
pids=()
timeout 10 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 1 terminated successfully"' &
pids+=($!)
timeout 2 bash -c 'sleep 5; echo "$(date +%H:%M:%S): job 2 terminated successfully"' &
pids+=($!)
wait "${pids[@]}"
echo "$(date +%H:%M:%S): done waiting. both jobs terminated on their own or via timeout; resuming script"
.
$ ./t.sh
08:59:42: start
08:59:47: job 1 terminated successfully
08:59:47: done waiting. both jobs terminated on their own or via timeout; resuming script
Zapište PID do souborů a spusťte aplikace takto:
pidFile=...
( app ; rm $pidFile ; ) &
pid=$!
echo $pid > $pidFile
( sleep 60 ; if [[ -e $pidFile ]]; then killChildrenOf $pid ; fi ; ) &
killerPid=$!
wait $pid
kill $killerPid
To by vytvořilo další proces, který po vypršení časového limitu usne a ukončí proces, pokud dosud nebyl dokončen.
Pokud se proces dokončí rychleji, PID soubor se odstraní a zabijácký proces se ukončí.
killChildrenOf
je skript, který načte všechny procesy a zabije všechny potomky určitého PID. V odpovědích na tuto otázku naleznete různé způsoby implementace této funkce:Nejlepší způsob, jak zabít všechny podřízené procesy
Pokud chcete vystoupit z BASH, můžete zapsat PID a časové limity do adresáře a sledovat tento adresář. Zhruba každou minutu si přečtěte záznamy a zkontrolujte, které procesy stále existují a zda nevypršel časový limit.
UPRAVIT Pokud chcete vědět, zda proces úspěšně skončil, můžete použít kill -0 $pid
EDIT2 Nebo můžete zkusit skupiny procesů. kevinarpe řekl:Chcete-li získat PGID pro PID(146322):
ps -fjww -p 146322 | tail -n 1 | awk '{ print $4 }'
V mém případě:145974. Pak lze PGID použít se speciální možností kill k ukončení všech procesů ve skupině:kill -- -145974