2014-11-14 11 views
6

ctrl-z (^ z) agisce in modi che non capisco quando viene eseguito all'interno di un ciclo eseguito da un terminale.bg/fg all'interno di un loop di riga di comando

Say I tipo

for ii in {0..100}; do echo $ii; sleep 1; done 

poi premere^z. Prendo:

[1]+ Stopped     sleep 1 

posso riprendere il lavoro utilizzando fg o bg, ma il lavoro si riferisce solo a lui dormire comando. Il resto del ciclo è apparentemente scomparso e sul terminale non appare più alcun numero.

potevo usare & dopo il comando da eseguire immediatamente in background, o un'altra soluzione è quello di avvolgere il tutto in una subshell:

(for ii in {0..100}; do echo $ii; sleep 1; done) 

poi^z mi dà

[1]+ Stopped     (for ii in {0..100}; 
do 
    echo $ii; sleep 1; 
done) 

Questo lavoro può essere ripreso e tutti sono felici. Ma di solito non ho l'abitudine di farlo quando eseguo un compito unico, e la domanda che pongo è perché il primo comportamento si verifica in primo luogo. C'è un modo per sospendere un loop della riga di comando che non è sottosuccesso? E cosa è successo al resto del ciclo nel primo esempio?

Si noti che questo è specifico per il ciclo:

echo 1; sleep 5; echo 2 

e colpire^z durante il sonno provoca la echo 2 da eseguire:

1 
^Z 
[2]+ Stopped     sleep 5 
2 

o devo solo prendere l'abitudine di usare & e chiama magia oscura?

risposta

5

Non è possibile sospendere l'esecuzione della shell corrente . Quando esegui il loop dalla riga di comando, è in esecuzione nella tua shell/terminale di accesso corrente. Quando premi [ctrl + z] stai dicendo alla shell di sospendere il processo attivo corrente. Il tuo ciclo è semplicemente un contatore nella shell corrente, il processo che viene eseguito è sleep. Sospendere funziona solo durante il sonno.

Quando si esegue il backgroud di un processo o si esegue in una subshell (approssimativamente equivalente), è possibile sospendere il processo separato in totale.

+1

Ma se la sospensione funziona solo su quel singolo comando di sospensione, perché non eseguono il resto dei comandi (come nell'esempio 1, sleep 5; esempio echo 2)? Mi aspetterei in quel caso che il sonno si sospenda e il resto del ciclo continui immediatamente. Sembra che z non abbia solo sospeso il sonno ma abbia anche ucciso il ciclo, e questo è quello che non capisco. –

+1

Sì, uccide il ciclo. Hai detto a bash di sospendere ciò che sta facendo. L'unica parte di ciò che può sospendere è il sonno. Il resto va via. Cercherò un riferimento per te. Leggi 'man bash (JOB CONTROL)' Il motivo è che, quando viene richiamata la sospensione, il controllo deve tornare alla shell. Non è possibile mantenere il ciclo attualmente in esecuzione mentre si restituisce il controllo alla shell e, poiché non ha una pipeline separata che può essere sospesa, termina per restituire il controllo a bash. –

Problemi correlati