Bash関数の暗黙的な戻り値?

Bash関数の暗黙的な戻り値?

다음과 같은 bash 기능이 있다고 가정해 보겠습니다.

gmx(){
  echo "foo";
}

関数はコマンドの終了値を暗黙的に返しますかecho、それともreturnを使用する必要がありますか?

gmx(){
  echo "foo";
  return $?
}

私はbashがどのように機能するか、bash関数の最後のコマンドの終了状態が「return」状態であると仮定していますが、100%確信できません。

答え1

return何かを作る明らかにシェル関数または「ドットスクリプト」(ソーススクリプト)から返されます。実行されない場合は、returnシェル関数またはドットスクリプトの末尾から暗黙的に返されます。

パラメータなしで実行すると、return最後に実行したコマンドの終了ステータスを返すのと同じです。

これがreturnすべてのPOSIXシェルで機能する方法です。

例えば、

gmx () {
  echo 'foo'
  return "$?"
}

したがって、次のようになります。

gmx () {
  echo 'foo'
  return
}

これは次のとおりです。

gmx () {
  echo 'foo'
}

一般的に言って使用する必要はほとんどありません$?。実際には、後で使用するために保存する必要がある場合にのみ必要です。たとえば、その値を複数回調査する必要がある場合(この場合、その値を変数に割り当てて一連のテストを実行します)。

答え2

bash(1)マニュアルページから:

実行時の関数の終了状態は、関数本体で実行された最後のコマンドの終了状態です。

答え3

すでに提供されている回答にいくつかの注意事項を追加します。

  • シェルには非常に特別な意味がありますが、return構文の観点から見ると、これはシェル組み込みコマンドであり、returnステートメントは他の単純なコマンドのように解析されます。これは、他のコマンドの引数と同様に、引用符が$?ない場合はSplit + globの影響を受けることを意味します。

    $?したがって、これを防ぐために引用する必要があります。

    return "$?"
    
  • return通常、どのオプションも受け入れません(ksh93'sは一般的な--help、、 ...--man--author受け入れますが)。予想される唯一の引数(オプション)は戻りコードです。許容される戻りコードの範囲はシェルによって異なり、$?0..255以外の値が正しく反映されるかどうかも同様です。バラよりプロセスの終了時にデフォルトの終了コードは何ですか?詳細。

    ほとんどのシェルは負の数を受け入れます。 (最終的には_exit()/exitgroup()システムコールに渡された引数があるintため、値には少なくとも-2 31から2 31 -1が含まれているため、シェルが同じ範囲の関数のみを受け入れるのは合理的です。)。

    ほとんどのシェルはwaitpid()および共同を使用します。終了ステータスを取得するためのAPIですが、この場合は0から255までの数字に切り捨てられます。保存済み存在する$?。関数呼び出しにはプロセスの生成と終了状態の検索は含まれませんが、waitpid()すべてが同じプロセス内で実行されるため、多くのシェルも関数をwaitpid()呼び出すときにこの動作を模倣します。つまりreturn、負の値で呼び出しても正の数$?は含まれるという意味です。

    負の数(ksh88、ksh93、bash、zsh、pdksh、およびmksh、yashを除く派生)を許可するシェルでは、一部(pdkshとyash)はこれを3、無効なオプションでreturn作成する必要があります。return -- -123-123-1-2-3

    pdkshとその派生(OpenBSDshやpdkshなどposh)は負のままで、負の数が含まれていると$?実行が失敗することを意味しますreturn "$?"(最後のコマンドの実行が負の数を返す関数の場合に発生します)。$?

    だからreturn -- "$?"その殻には良いです。ただし、ほとんどのシェルはこの構文をサポートしていますが、POSIXではなく、実際にmkshash派生ではサポートされていません。

    つまり、要約すると、pdkshベースのシェルは関数引数に負の数を使用できますが、そうするとreturn "$@"機能しません。動作する他のシェルでは、return "$@"負数(または0..255以外の数字)を引数として使用しないでくださいreturn

  • 私が知っているすべてのシェルでreturn関数内で実行されているサブシェル内で呼び出すと、サブシェルは終了しますが(提供された終了状態がある場合、または最後のコマンド実行の終了状態に)、そうでなければそうではありません。関数(POSIXがそのような保証を提供しているかどうかはわかりません。一部の人はexit関数内のサブシェルを終了するために使用する必要があると思います)。例えば

    f() {
      (return 3)
      echo "still inside f. Exit status: $?"
    }
    f
    echo "f exit status: $?"
    

    以下を出力します。

    still inside f. Exit status: 3
    f exit status: 0
    

関連情報