終了コマンドの終了コードをキャプチャする


10

私はこれをbashスクリプトに入れています:

exit 3;

exit_code="$?"

if [[ "$exit_code" != "0" ]]; then
    echo -e "${r2g_magenta}Your r2g process is exiting with code $exit_code.${r2g_no_color}";
    exit "$exit_code";
fi

exitコマンドの直後に終了するように見えますが、これは理にかなっています。私はすぐに終了せずに終了コードを提供できるいくつかの簡単なコマンドがあるのだろうかと思っていましたか?

私は推測するつもりでした:

exec exit 3

しかし、エラーメッセージが表示されますexec: exit: not found。私に何ができる?:)


1
うんexec exit 3何ブエノではありません、私が取得"exec: exit: not found"

7
質問が理解できません。ラインを設定exit_code=3してexit 3完全に削除しませんか?
wjandrea 2018

@wjandreaは実用的というより概念的な質問です

2
それでも私には意味がありません。実際に終了しないと、なぜ終了コードがあるのですか?
Barmar 2018

1
@Barmarすべてのプロセスには終了コードがあります。質問に答えようとする人のほとんどは、質問を「スクリプトで「exit 3」を何に置き換えれば、$?変数を設定してこのスクリプトを終了しないのか」と解釈していますか?
icarus

回答:


32

いくつかのプログラムを実行してプログラムの終了ステータスを(で  $?)確認するスクリプトがあり、何らかの既知の値(たとえば)に設定される  ようにする ことによってそのスクリプトをテストしたい場合は、$?3

(exit 3)

括弧はサブシェルを作成します。次に、exitコマンドはそのサブシェルを指定された終了ステータスで終了させます。


また、デバッグの目的でexit_code="3"テストを設定するのも同じくらい簡単です
Centimane


12

exitはbashの組み込みなので、できませんexecバッシュのマニュアルごと:

Bashの終了ステータスは、スクリプトで実行された最後のコマンドの終了ステータスです。コマンドが実行されない場合、終了ステータスは0です。

これらすべてをまとめると、必要な終了ステータスを変数に格納し、その後exit $MY_EXIT_STATUS適切な場合にのみ、あなたの唯一のオプションと思います。


@ G-manのアイデアについてどう思いますか?

2
多分私はあなたが達成しようとしていることを誤解しました。設定しようとしているだけなら$?(なぜそうするのか本当にわからないけれど)、それは確かな答えのように思えます。失敗した値に設定するだけの場合falseは、別のオプションです。
solarshado

10

引数として、または255何も指定されていない場合は、ステータスを返す関数を作成できます。(retその値を「返す」ので、私はそれを呼び出します。)

ret() { return "${1:-255}"; }

へのret呼び出しの代わりに使用しますexit。これにより、現在受け入れられている回答でサブシェルを作成する非効率性を回避できます。

いくつかの測定。

time bash -c 'for i in {1..10000} ; do (exit 3) ; done ; echo $?'

私のマシンでは約3.5秒かかります。

 time bash -c 'ret(){ return $1 ; } ; for i in {1..10000} ; do ret 3 ; done ; echo $?'

私のマシンでは約0.051秒かかり、70倍高速です。デフォルトの処理を行うと、60倍速くなります。ループには明らかにオーバーヘッドがあります。私はちょうどであることをループの本体を変更した場合:true、時間が0.025に半減され、完全に空のループが無効な構文です。;:ループに追加すると、この最小限のコマンドには0.007秒かかるため、ループのオーバーヘッドは約0.018です。2つのテストからこのオーバーヘッドを差し引くと、retソリューションが100倍以上速くなることがわかります。

明らかにこれは総合的な測定ですが、状況はさらに複雑になります。すべてを必要以上に100倍遅くすると、システムが遅くなります。0.0


2
@iBug余分なスペースは必要ありません。
icarus

サブシェルを作成する非効率性についての良い点。一部のシェルは、このような場合にフォークを最適化するのに十分スマートである可能性があることを読みましたが、そのbashはそれらの1つではありません。
G-Manは 'Reinstate Monica'

3

についてexec exit 3...という外部コマンドを実行しようとしますが、外部コマンドexitがないため、エラーが発生します。シェルを完全にexec 置き換えるため、シェルに組み込まれているコマンドではなく、外部コマンドである必要あります。また、あなたはどちらと呼ばれる外部コマンドを持っていた場合でも手段exitexec exit 3以来、あなたのシェルスクリプトを継続するために返さないでしょうシェルがこれ以上存在しないだろう


1
私はあなたができると思いますがexec bash -c "exit 3"、今のところ、それをする理由とは対照的に、それを行う理由を考えることはできませんexit 3
David Z

1
@DavidZは、いずれにしても、exec「する」またはexit「単に」するだけでスクリプトを停止します。これは、質問が望んでいたようには見えませんでした。
ilkkachu

3

Awkでこれを行うことができます:

awk 'BEGIN{exit 9}'

またはSed:

sed Q9 /proc/stat

...またはシェルを使用:sh -c 'exit 9'
ilkkachu 2018

1
@ilkkachuもしあなたがそうするつもりなら、あなたも(exit 9)受け入れられた答えでそうするかもしれません
Steven Penny
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.