Come posso eseguire un comando e ottenere il suo codice di uscita in meno caratteri?


13

Scrivevo i miei script in questo modo:

some_command
while [ $? -ne 0 ] ; do
    sleep 1
    some_command
done

Mi ha sempre infastidito il fatto che devo scrivere some_commanddue volte. Posso metterlo in qualche modo nella sezione test del loop?

Risposte:


20

È possibile utilizzare some_commandcome condizione di prova.

while ! some_command; do sleep 1; done

La condizione rimarrà vera fino a quando some_commandesce con un errore.

O un modo più dettagliato se vuoi fare ulteriori controlli:

while ! some_command
do 
    # add more if desired
    sleep 1
done

Sembra migliore del mio, anche se è un one-liner ;-)
Anthon,

L'OP potrebbe voler dividerlo in più righe se dovesse aver bisogno di eseguire diversi comandi in caso di fallimento, però :)
John WH Smith

Non c'è motivo per cui non sia possibile interromperne la linea ai punti e virgola per renderla multilinea.
Mark Stewart,

1
... oppure scriviwhile ! some_command; do several; commands; sleep 1; done
ignis il

12

Ecco a cosa serve il untilloop:

until some_command
do    sleep 1
done

È la negazione logica di un whileciclo.

Le specifiche dicono:

The untilLoop

  • Il untilloop deve eseguire continuamente un elenco composto purché un altro elenco composto abbia uno stato di uscita diverso da zero.

  • Il formato del ciclo until è il seguente:

    fino a compound-list-1
    fare compound-list-2
    fatto
  • L' elenco composto-1 deve essere eseguito e, se ha uno stato di uscita pari a zero, il untilcomando viene completato. Altrimenti, l' elenco composto-2 deve essere eseguito e il processo si ripete.

4

Puoi semplicemente fare:

false
while [ $? -ne 0 ] ; do
   sleep 1
   some_command
done

questo ha lo svantaggio però che dorme sempre prima un secondo

Se vuoi essere in grado di uscire da uno qualsiasi dei vari comandi per uscire con 0 puoi fare:

while true; do
  if [ some_command ] ; then break ; fi
  if [ some_other_command ] ; then break ; fi
  sleep 1
done

che ovviamente funziona anche per giusto some_command


5
Il secondo esempio non dovrebbe includere [e ]attorno ai comandi.
nyuszika7h,

2

while ! ...until ...opere sui sistemi che congelava loro ambiente shell prima POSIX.1-2001. Questo, tuttavia, lo fa.

while :; do
    if some command; then
        break
    fi
    sleep 1
done

Se non hai bisogno di portabilità totale, perché stai scrivendo uno script di shell? È più probabile che Perl sia disponibile rispetto a Bash.

sleep 1 while 0 != system qw(some command);

(Come sopra, sleepviene eseguito solo se il comando non riesce.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.