シェル スクリプトはコマンドを順番に実行しますか?

シェル スクリプトはコマンドを順番に実行しますか?

少し不安定で、時々 SSL エラーが発生する Python スクリプトがあります。この例外は、ライブラリの奥深くに埋め込まれた関数によって発生するため、基本的に修正方法はありません。

私は、何度も実行される 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スクリプトの残りの部分を実行する前に のみ待機しますが、一部のシェルは両方を待機します。2 番目のケースでは、シェルはcmd2(cmd1は非同期的に実行される (または対話型シェルで実行される場合はバックグラウンドで実行される) と言われます) のみを待機し、3 番目のケースでは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ループ内のプログラムの終了コードが何であっても問題ありません。プログラムは記述された順序で実行され続けます。

このようにすると効率的ですか? もっと良い方法はないでしょうか?

最高それを実現する方法は、Python プログラムのバグを潰すことです。

答え3

タイトルの質問にお答えします。はい、シェル スクリプト内のコマンドは順番に同期して実行されるため、Python スクリプトの実行中はシェルがブロックされます。

エラーの原因を修正する方が確かに良いのですが、それができない場合は、ゼロのステータス コード ( while true;do ./script.py; if [[ "$?" = 0]];break;done) が返されるまで Python スクリプトを実行しようとするシェル スクリプトが賢明なアプローチです。

関連情報