¿Cómo ejecuto un comando y obtengo su código de salida en menos caracteres?

13

Solía ​​escribir mis guiones así:

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

Siempre me molestó que tuviera que escribir some_commanddos veces. ¿Puedo ponerlo dentro de la sección de prueba de bucle de alguna manera?

Mihai
fuente

Respuestas:

20

Podrías usarlo some_commandcomo tu condición de prueba.

while ! some_command; do sleep 1; done

La condición seguirá siendo válida siempre que some_commandsalga con un error.

O una forma más detallada si desea hacer verificaciones adicionales:

while ! some_command
do 
    # add more if desired
    sleep 1
done
John WH Smith
fuente
Esto se ve mejor que el mío, a pesar de que es de una sola línea ;-)
Anthon
El PO puede ser que desee dividirlo en varias líneas en caso de que necesite para ejecutar varios comandos en caso de fallo, sin embargo :)
John Smith WH
No hay razón por la que no pueda dividirlo en los puntos y coma para que sea multilínea.
Mark Stewart
1
... o escribewhile ! some_command; do several; commands; sleep 1; done
ignis
12

Para esto es el untilciclo:

until some_command
do    sleep 1
done

Es la negación lógica de un whilebucle.

La especificación dice:

El untilbucle

  • El untilbucle deberá ejecutar continuamente una lista compuesta siempre que otra lista compuesta tenga un estado de salida distinto de cero.

  • El formato del bucle hasta es el siguiente:

    hasta compuesto-lista-1
    hacer compuesto-lista-2
    hecho
  • El compuesto-list-1 se ejecutará, y si tiene un código de salida de cero, los untilcomplete el mandato. De lo contrario, se debe ejecutar el compuesto-lista-2 y el proceso se repite.
mikeserv
fuente
4

Solo puedes hacer:

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

esto tiene la desventaja de que siempre duerme un segundo primero

Si desea poder salir de cualquiera de una serie de comandos para salir con 0, puede hacer:

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

que por supuesto también funciona solo some_command

Anthon
fuente
55
El segundo ejemplo no debe incluir [y ]alrededor de los comandos.
nyuszika7h
2

Ni while ! ...tampoco until ...trabajos sobre los sistemas que congelaron su entorno de shell antes de la POSIX.1-2001. Esto, sin embargo, lo hace.

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

Si no necesita portabilidad total, ¿por qué está escribiendo un script de shell? Es más probable que Perl esté disponible que Bash.

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

(Como se indicó anteriormente, sleepsolo se ejecuta si el comando falla).

zwol
fuente