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 cmd2
execução depende do cmd1
sucesso (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 cmd2
antes 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
( cmd2
assí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, cmd4
será executado por último.
Em:
cmd1 =(cmd2) # zsh
Eles são executados sequencialmente ( cmd2
primeiro).
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, true
nã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.