У меня есть скрипт на Python, который немного нестабилен и время от времени выдает ошибку SSL. Исключение вызывается какой-то функцией, зарытой глубоко в какой-то библиотеке, так что по сути нет способа исправить это.
Я реализовал хакерское решение, создав скрипт оболочки с циклом while, который выполняется большое количество раз, и выполнив скрипт Python внутри этого цикла.
Теперь я надеюсь, что при запуске итерации цикла и выполнении скрипта цикл внутри скрипта оболочки останется на месте до тех пор, пока скрипт Python не завершится сбоем, а следующая итерация цикла не выполнит скрипт повторно и так далее.
Эффективно ли это делать? Есть ли лучший способ сделать это? И самое главное, правильно ли это?
решение1
В:
cmd1
cmd2
или
cmd1; cmd2
Они выполняются последовательно.
В
cmd1 && cmd2
Или
cmd1 || cmd2
Они выполняются последовательно, но cmd2
выполнение их вообще зависит от того, будет ли cmd1
они успешными (для &&
) или неудачными (для ||
).
В
cmd1 | cmd2
или
cmd1 & cmd2
cmd1 |& cmd2 # ksh
coproc cmd1; cmd2 # bash/zsh
или
cmd1 <(cmd2) # ksh/zsh/bash (also yash though with a different meaning)
Они выполняются одновременно. В первом случае некоторые оболочки ждут только cmd2
перед продолжением выполнения остальной части скрипта, а некоторые ждут и того, и другого. Во втором случае оболочки ждут только cmd2
( cmd1
говорят, что они выполняются асинхронно (или в фоновом режиме, если запущены в интерактивной оболочке)), а в третьем — cmd1
( cmd2
асинхронно).
В:
< "$(cmd1)" x=$(cmd2) y=$(cmd3) cmd4 "$(cmd5)" > "$(cmd6)"
Команды выполняются последовательно, но порядок зависит от оболочки. В любом случае cmd4
будет выполнена последней.
В:
cmd1 =(cmd2) # zsh
Они выполняются последовательно ( cmd2
сначала).
Обратите внимание, что во всех этих случаях любая из этих команд может запустить другие процессы. Оболочка не будет знать о них, поэтому не сможет их ждать.
решение2
Да. Это верно. Подумайте об этом:
#!/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
...после выполнения будет выглядеть так:
./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
Пока цикл всегда, true
не имеет значения, какие коды выхода имеют программы внутри цикла. Они продолжат выполняться в той последовательности, в которой они написаны.
Эффективно ли это делать? Есть ли способ лучше?
Theлучшийспособ сделать это — устранить ошибку в вашей программе Python!
решение3
Отвечая на ваш вопрос в заголовке: да, команды в скрипте оболочки выполняются синхронно и последовательно, поэтому оболочка блокируется во время выполнения скрипта Python.
Конечно, было бы лучше устранить источник ошибки, но если это невозможно, то while true;do ./script.py; if [[ "$?" = 0]];break;done
разумным подходом будет сценарий оболочки, который попытается запустить сценарий Python до тех пор, пока он не вернет нулевой код состояния ( ).