web-dev-qa-db-ja.com

Linuxの終了コードの最小値と最大値は何ですか?

Linuxの次の終了コードの最小値と最大値は何ですか。

  1. バイナリ実行可能ファイル(Cプログラムなど)から返された終了コード。
  2. Bashスクリプトから返された終了コード(exitを呼び出すとき)。
  3. 関数から返された終了コード(returnを呼び出したとき)。これは0および255
45
user271801

_exit()/exit_group()システムコールに渡される番号(exit codeと呼ばれることもあります。これはexit statusとのあいまいさを回避するために、いずれかの終了コードのエンコーディングも参照していますまたはプロセスが強制終了されたか正常に終了したかに応じて信号番号と追加情報)はタイプintであるため、LinuxなどのUnixライクなシステムでは、通常-2147483648(-231)〜2147483647(231-1)。

ただし、すべてのシステムで、親プロセス(または親が死亡した場合は子サブリーパーまたはinit)がwait()waitpid()wait3()wait4()システムコールを使用してそれを取得すると、その下位8ビットのみが使用可能(値0から255(28-1))。

waitid() API(またはSIGCHLDのシグナルハンドラー)を使用する場合、ほとんどのシステム(および 標準の2016年版でPOSIXがより明確に要求するようになりました_exit()仕様 を参照))、完全な番号が使用可能です(返された構造のsi_statusフィールドで)。 Linuxではまだそうではありませんが、waitid() APIで数値を8ビットに切り捨てますが、将来的には変更される可能性があります。

多くのシェルはexit status$?表現で128を超える値を使用して信号をエンコードするため、通常、値0(通常は成功を意味する)から125のみを使用する必要があります。強制終了されるプロセスの数、および特別な条件の場合は126と127。

シェルの$?と同じことを意味するために、exit()で126〜255を使用することができます(スクリプトがret=$?; ...; exit "$ret"を実行する場合など)。 0-> 255以外の値を使用しても、通常は役に立ちません。一般的には、切り捨てを行わないシステムで親がwaitid() APIを使用することがわかっていて、32ビットの範囲の値が必要な場合にのみ、これを行います。たとえば、exit(2048)を実行すると、親は従来のwait*() APIを使用して成功したと見なされます。

詳細:

このQ&Aは、他のほとんどの質問にうまく回答し、exit statusの意味を明確にする必要があります。さらにいくつか追加します。

プロセスが強制終了されるか、_exit()/exit_group()システムコールを呼び出さない限り、プロセスは終了できません。 Cmain()から戻ると、libcはそのシステムコールを戻り値で呼び出します。

ほとんどの言語には、そのシステムコールをラップするexit()関数があり、一般にシステムコールに渡される場合は、それらの関数が取る値があります。 (それらは一般に、Cのexit()関数がstdioバッファーをフラッシュし、atexit()フックを実行することによって行われるクリーンアップのような多くのことを行うことに注意してください)

それは少なくともの場合です:

$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234)                        = ?
$ strace -e exit_group Perl -e 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234)                        = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234)                        = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)

0-255以外の値を使用すると文句を言う人がときどきいます。

$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1)                           = ?

一部のシェルは、負の値を使用すると文句を言います。

$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2)                           = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2)                           = ?

POSIXは、exit特殊組み込みに渡された値が0-> 255以外の場合、動作を未定義のままにします。

次の場合、一部のシェルは予期しない動作を示します。

  • bash(およびmkshではなく、それが基づいているpdkshではない)は、値を8ビットに切り捨てます。

    $ strace -e exit_group bash -c 'exit 1234'
    exit_group(210)                         = ?
    

    したがって、これらのシェルで、0〜255以外の値で終了する場合は、次のようにする必要があります。

    exec zsh -c 'exit -- -12345'
    exec Perl -e 'exit(-12345)'
    

    つまり、同じプロセスで別のコマンドを実行しますcan必要な値でシステムコールを呼び出します。

  • 他のQ&Aで述べたように、ksh93は257から256 + max_signal_numberまでの終了値に対して最も奇妙な動作をします。この場合、exit_group()を呼び出す代わりに、対応するシグナルで自分自身を殺します¹。

    $ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    zsh: suspended (signal)  ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    

    それ以外の場合は、bash/mkshのように数値を切り捨てます。


¹ただし、次のバージョンでは変更される可能性があります。 ksh93の開発がAT&T以外のコミュニティの取り組みとして引き継がれたので、 POSIXによって何らかの形で奨励されているにもかかわらず、その動作は元に戻されています

77

最小は0、それは成功値と見なされます。他のすべては失敗です。最大は255 としても知られている -1

これらのルールは、スクリプトとその他の実行可能ファイル、およびシェル関数の両方に適用されます。

より大きな値は256を法とする結果になります。

12
user147505

これはとてもシンプルに見えますが、ああ、悲惨です。

C言語(および他のほとんどの言語に直接または間接的に従う)では、mainから戻ることは、戻り値と同じ引数でexitを呼び出すことと同等である必要があります。これは整数です(戻り値の型は非常に明確にintです)。そのため、原則として範囲はINT_MINからINT_MAXになります。

ただし、 POSIXの状態 は、exitに渡された最下位の8ビットのみが、文字どおり "status&0xFF"
そのため、実際には、終了コードは(まだ符号付きの)整数であり、その最下位8ビットのみが設定されています。

したがって、最小値は-128、最大値は127になります。。ちょっと待ってください、それは本当ではありません。 0〜255です。

しかし、悲しいかなもちろん、それほど単純なことはできません。実際には、Linux(またはbash) 別の方法で行います 。戻りコードの有効な範囲は0から255(つまり、符号なし)です。

混乱を避けるために安全を期すには、リターンコードが署名されていないことを仮定し、waitから返されたものをすべて署名なしにキャストすることをお勧めします。そうすることで、シェルに表示されるものと一致します。最上位ビット(最上位ビットを含む)はクリアされるので、技術的には署名されていますが、実際の値は常に符号なしであるため(符号ビットが設定されないため)、それは「誤り」でもありません。
これは、終了コードを-1と比較する一般的なエラーを回避するのにも役立ちます。これは、プログラムが-1で終了した場合でも奇妙な理由で表示されないようです( 、理由を推測してください!).

最後のポイントについて、関数から戻るときに、この関数がたまたまmainである場合は、上記を参照してください。それ以外の場合は、関数の戻り値の型によって異なりますが、原則としてanythingvoidを含む)になります。

6
Damon
  1. バイナリ実行可能ファイル(Cプログラムなど)から返された終了コード。
  2. Bashスクリプトから返された終了コード(exitを呼び出すとき)。

任意のプロセスからの終了コード-バイナリ実行可能ファイル、シェルスクリプト、またはその他のもの-の範囲は0から255です。exit()に渡せる値は大きいですが、下位8ビットのみですステータスのwait()を介して他のプロセスが利用できるようになります。

  1. 関数から返された終了コード(returnを呼び出したとき)。これは0から255の間だと思います。

C関数は、ほとんどすべての型を返すものとして宣言できます。戻り値の制限は、そのタイプによって完全に決定されます。たとえば、signed charを返す関数の場合は-128〜127、unsigned intを返す関数の場合は0〜42億、または任意の浮動小数点infを返す関数の場合、doubleまでの数。そして、それはvoid *struct...のような非数値型を数えていません...

2