Um script Shell executa comandos sequencialmente?

Um script Shell executa comandos sequencialmente?

Eu tenho um script python que é um pouco instável e apresenta um erro de SSL de vez em quando. A exceção é levantada por alguma função enterrada em alguma biblioteca, portanto, essencialmente, não há solução para ela.

Implementei uma solução hacky criando um script de shell com um loop while que é executado um grande número de vezes e executando o script python a partir desse loop.

Agora, o que espero é que, à medida que uma iteração do loop seja iniciada e o script seja executado, o loop dentro do shell script permaneça onde está até que o script python falhe e a próxima iteração do loop execute novamente o script e assim sobre.

Fazer assim é eficiente? Existe uma maneira melhor de fazer isso? e o mais importante, está correto?

Responder1

Em:

cmd1
cmd2

ou

cmd1; cmd2

Eles são executados sequencialmente.

Em

cmd1 && cmd2

Ou

cmd1 || cmd2

Eles são executados sequencialmente, mas a cmd2execução depende do cmd1sucesso (for &&) ou da falha (for ||).

Em

cmd1 | cmd2

ou

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

ou

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

Eles são executados simultaneamente. No primeiro caso, alguns shells apenas esperam cmd2antes de continuar com o restante do script, enquanto outros esperam por ambos. No segundo caso, os shells apenas esperam por cmd2( cmd1é considerado executado de forma assíncrona (ou em segundo plano quando executado em um shell interativo)) e no terceiro for cmd1( cmd2assíncrono).

Em:

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

Os comandos são executados sequencialmente, mas a ordem depende do shell. Em qualquer caso, cmd4será executado por último.

Em:

cmd1 =(cmd2) # zsh

Eles são executados sequencialmente ( cmd2primeiro).

Observe que em todos esses casos, qualquer um desses comandos poderia iniciar outros processos. A concha não teria conhecimento deles, então não pode esperar por eles.

Responder2

Sim. Isso está correto. Considere isto:

#!/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

... ficará assim quando executado:

./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

Contanto que o loop seja sempre, truenão importa quais códigos de saída os programas dentro do loop possuem. Eles continuarão a ser executados na sequência em que foram escritos.

Fazer assim é eficiente? Existe uma maneira melhor de fazer isso?

OmelhorUma maneira de fazer isso seria eliminar o bug no seu programa Python!

Responder3

Para responder à pergunta do título: Sim, os comandos em um script de shell são executados de forma síncrona em sequência, portanto, o shell é bloqueado enquanto o script Python está em execução.

Certamente seria melhor corrigir a origem do erro, mas se isso não for uma opção, um script shell que tentará executar o script python até retornar um código de status zero ( while true;do ./script.py; if [[ "$?" = 0]];break;done) é uma abordagem sensata.

informação relacionada