2012-06-26 14 views
7

Ho bisogno di eseguire l'applicazione in ogni X secondi, quindi, per quanto cron non funziona con i secondi in questo modo, ho scritto uno script di bash con ciclo infinito con X secondi in cui dormire.Come interrompere il ciclo infinito nello script bash con garbo?

Quando devo interrompere manualmente lo script in esecuzione, mi piacerebbe farlo in un modo corretto - lasciare che l'applicazione funzioni completamente e semplicemente non entrare nel ciclo per la prossima volta.

Avete qualche idea, come questo può essere raggiunto? Ho pensato di passare argomenti, ma non sono riuscito a trovare come passare argomenti a script in esecuzione.

risposta

22

Si potrebbe intrappolare un segnale, dicono SIGUSR1:

echo "My pid is: $$" 
finish=0 
trap 'finish=1' SIGUSR1 

while ((finish != 1)) 
do 
    stuff 
    sleep 42 
done 

Poi, quando si vuole uscire dal ciclo alla successiva iterazione:

kill -SIGUSR1 pid 

Dove pid è il processo-id del script. Se il segnale viene sollevato durante il sonno, si riattiverà (il sonno dorme fino a quando non si verifica alcun segnale).

+0

Grazie :) questo funziona –

2

È possibile passare alcuni argomenti da un file. Su ogni iterazione puoi leggere questo file e vedere se le tue condizioni sono state cambiate.

1

La seguente struttura può essere appropriata se è necessario eseguire comunque una pulizia. Usa kill come mostrato nella risposta di cdarke.

#=============================================================== 
# FUNCTION DEFINITIONS 
#=============================================================== 
# . . . 

#=== FUNCTION ================================================ 
#   NAME: cleanup 
# DESCRIPTION: 
#=============================================================== 
cleanup() 
{ 
    # wait for active children, remove empty logfile, ..., exit 
    exit 0 
} # ---------- end of function cleanup ---------- 

#=============================================================== 
# TRAPS 
#=============================================================== 
trap cleanup SIGUSR1 

#=============================================================== 
# MAIN SCRIPT 
#=============================================================== 
echo -e "Script '$0'/PID ${$}" 

while : ; do        # infinite loop 
    # . . . 
    sleep 10 
done 
# . . . 

#=============================================================== 
# STATISTICS/CLEANUP 
#=============================================================== 
cleanup 
0

La soluzione trappola postato in precedenza è un bene per i grandi cicli, ma ingombrante per il caso comune in cui si sono appena più di un loop alcuni comandi singoli o. In questo caso vi consiglio la seguente soluzione:

while whatever; do 
    command || break 
done 

Ciò terminerà il ciclo se comando ha un codice di uscita diverso da zero, che succede se essa viene interrotto. Quindi, a meno che lo command non funzioni SIGINT, premendo ctrl-C si arresta il comando corrente e si esce dal ciclo.

Modifica: dopo aver letto la domanda più da vicino, vedo che si desidera che il comando corrente continui a essere eseguito. In tal caso questa soluzione non si applica.

Problemi correlati