¿Un script de Shell ejecuta comandos secuencialmente?

¿Un script de Shell ejecuta comandos secuencialmente?

Tengo un script en Python que es un poco inestable y da un error de SSL de vez en cuando. La excepción surge de alguna función oculta en lo profundo de alguna biblioteca, por lo que esencialmente no hay solución.

Implementé una solución hacky creando un script de shell con un bucle while que se ejecuta una gran cantidad de veces y ejecutando el script de Python desde ese bucle.

Ahora lo que espero es que cuando comience una iteración del bucle y se ejecute el script, el bucle dentro del script de shell permanezca donde está hasta que el script de Python falle y la siguiente iteración del bucle vuelva a ejecutar el script y así. en.

¿Es eficiente hacerlo así? Hay una mejor manera de hacerlo? y lo más importante es correcto?

Respuesta1

En:

cmd1
cmd2

o

cmd1; cmd2

Se ejecutan secuencialmente.

En

cmd1 && cmd2

O

cmd1 || cmd2

Se ejecutan secuencialmente, pero si cmd2se ejecuta depende de si cmd1tiene éxito (para &&) o falla (para ||).

En

cmd1 | cmd2

o

cmd1 & cmd2
cmd1 |& cmd2 # ksh
coproc cmd1; cmd2 # bash/zsh

o

cmd1 <(cmd2) # ksh/zsh/bash (also yash though with a different meaning)

Se ejecutan simultáneamente. En el primer caso, algunos shells sólo esperan cmd2antes de continuar con el resto del script, mientras que otros esperan ambos. En el segundo caso, los shells solo esperan cmd2( cmd1se dice que se ejecuta de forma asíncrona (o en segundo plano cuando se ejecuta en un shell interactivo)) y en el tercero cmd1( cmd2asíncrono).

En:

< "$(cmd1)" x=$(cmd2) y=$(cmd3) cmd4 "$(cmd5)" > "$(cmd6)"

Los comandos se ejecutan secuencialmente, pero el orden depende del shell. En cualquier caso, cmd4se ejecutará en último lugar.

En:

cmd1 =(cmd2) # zsh

Se ejecutan secuencialmente ( cmd2primero).

Tenga en cuenta que en todos esos casos, cualquiera de esos comandos podría iniciar otros procesos. El caparazón no tendría conocimiento de ellos, por lo que no puede esperarlos.

Respuesta2

Sí. Es correcto. Considera esto:

#!/bin/bash

while true; do
    sleep 1
    echo "Slept 1"
    echo "Exit status $?, ok."
    sleep 1
    echo "Slept 1, now executing faulty command 'ps q'"
    ps q
    echo "Exit status $?, not ok. Loop continues forever..."
done

...se verá así cuando se ejecute:

./loop.sh 
Slept 1
Exit status 0, ok.
Slept 1, now executing faulty command 'ps q'
ps: illegal option -- q
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
          [-u]
          [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
       ps [-L]
Exit status 1, not ok. Loop continues forever...
Slept 1
Exit status 0, ok.
Slept 1, now executing faulty command 'ps q'
ps: illegal option -- q
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
          [-u]
          [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
       ps [-L]
Exit status 1, not ok. Loop continues forever...
^C

Mientras el bucle sea siempre, trueno importa qué códigos de salida tengan los programas dentro del bucle. Continuarán ejecutándose en la secuencia en la que están escritos.

¿Es eficiente hacerlo así? Hay una mejor manera de hacerlo?

Elmejor¡La forma de hacerlo sería eliminar el error en su programa Python!

Respuesta3

Para responder a la pregunta del título: Sí, los comandos en un script de shell se ejecutan sincrónicamente en secuencia, por lo que el shell se bloquea mientras se ejecuta el script de Python.

Ciertamente sería mejor corregir la fuente del error, pero si eso no es una opción, un script de shell que intentará ejecutar el script de Python hasta que devuelva un código de estado cero ( while true;do ./script.py; if [[ "$?" = 0]];break;done) es un enfoque sensato.

información relacionada