GNU/Linux >> Znalost Linux >  >> Linux

Bash:počkejte s časovým limitem

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


Linux
  1. Bash pole s příklady

  2. Bash If-Else prohlášení s příklady

  3. Alias ​​s proměnnou v bash

  1. Bash -c s pozičními parametry?

  2. základní jméno s mezerami ve skriptu bash?

  3. Přidání časového razítka k názvu souboru s mv v BASH

  1. Ekvivalent Waitpid s časovým limitem?

  2. Co dělá poll() s časovým limitem 0?

  3. Linux Bash XMLLINT s XPATH