Выполняет ли скрипт оболочки команды последовательно?

Выполняет ли скрипт оболочки команды последовательно?

У меня есть скрипт на 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 до тех пор, пока он не вернет нулевой код состояния ( ).

Связанный контент