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

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

少し不安定で、時々SSLエラーを引き起こすPythonスクリプトがあります。一部のライブラリに深く埋め込まれた一部の関数によって例外が発生するため、デフォルトでは回避策はありません。

私は何度も実行されるwhileループを使用してシェルスクリプトを生成し、ループ内でPythonスクリプトを実行してハッキーソリューションを実装しました。

今私が望むのは、ループ反復が開始され、スクリプトが実行されたときにPythonスクリプトが失敗し、ループの次の反復がスクリプトを再実行するまで、シェルスクリプト内のループが元の場所に保持されることです。 。

これは効率的ですか?もっと良い方法がありますか?最も重要なことは正しいですか?

答え1

存在する:

cmd1
cmd2

または

cmd1; cmd2

順次実行されます。

存在する

cmd1 && cmd2

または

cmd1 || cmd2

順番に実行されますが、cmd2実行されるかどうかは完全にcmd1成功(for &&)または失敗(for ||)によって異なります。

存在する

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番目のケースでは、シェルは待機しますcmd2cmd1非同期的に実行されるといいます(またはインタラクティブシェルで実行されている場合はバックグラウンドで実行されます))。一方、3番目のケースではcmd1cmd2非同期的に)実行されます。

存在する:

< "$(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スクリプトを実行しようとするのが賢明なアプローチです()。

関連情報