web-dev-qa-db-ja.com

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

私はこれを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。私に何ができる? :)

10
user287203

一部のプログラムを実行し、プログラムの終了ステータスを確認するスクリプトがある場合($?)、そしてsomethingを実行してそのスクリプトをテストすると、$?を既知の値に設定します(例:3)、ただやる

(exit 3)

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

exitはbashの組み込みなので、execすることはできません。あたり bash's manual

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

これらすべてをまとめると、あなたの唯一の選択肢は、目的の終了ステータスを変数に格納してからexit $MY_EXIT_STATUS適切な場合。

12
solarshado

引数として指定されたステータスを返す関数を記述できます。指定されていない場合は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

10
icarus

exec exit 3について... exitという外部コマンドを実行しようとしますが、存在しないため、エラーが発生します。 execはシェルを完全に置き換えるため、シェルに組み込まれたコマンドではなく、外部コマンドである必要があります。これは、exitという外部コマンドがあったとしても、シェルがそこにないため、exec exit 3はシェルスクリプトを続行するために戻らないことを意味しますこれ以上

3
ilkkachu

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

awk 'BEGIN{exit 9}'

またはSed:

sed Q9 /proc/stat
3
Steven Penny