シェルスクリプトを学習しようとしていますが、他の人のコードを理解する必要があります。 $?
変数ホールドとは何ですか?句読文字をブロックするため、Googleで回答を検索できません。
$?
は、最後に実行されたコマンドの戻り値を見つけるために使用されます。シェルで次のことを試してください。
ls somefile
echo $?
somefile
が存在する場合(ファイルかディレクトリかに関係なく)、ls
コマンドによってスローされる戻り値を取得します。これは、0
(デフォルトの「成功」戻り値)でなければなりません。存在しない場合は、0以外の数値を取得する必要があります。正確な数値はプログラムによって異なります。
多くのプログラムでは、対応するマニュアルページで数字とその意味を見つけることができます。これらは通常「終了ステータス」として説明され、独自のセクションを持つ場合があります。
これは、最後に実行された機能/プログラム/コマンドの終了ステータスです。参照する:
以前に実行されたプロセスの戻り値。
10.4プログラムの戻り値の取得
Bashでは、プログラムの戻り値は$?という特別な変数に格納されます。
これは、プログラムの戻り値をキャプチャする方法を示しています。ディレクトリdadaが存在しないと仮定しています。 (これはマイクによっても提案されました)
#!/bin/bash cd /dada &> /dev/null echo rv: $? cd $(pwd) &> /dev/null echo rv: $?
詳細については、 Bash Programming Manual を参照してください。
最小限のPOSIX C終了ステータスの例
$?
を理解するには、最初にプロセス終了ステータスの概念を理解する必要があります。
Linuxの場合:
プロセスがexit
システムコールを呼び出すと、カーネルはプロセスが終了した後でもシステムコールに渡された値を保存します。
Exitシステムコールは、exit()
ANSI C関数によって呼び出され、return
からmain
を実行すると間接的に呼び出されます。
多くの場合fork
+ exec
で終了する子プロセス(Bash)を呼び出したプロセスは、wait
システムコールで子の終了ステータスを取得できます。
Bashコードを検討してください。
$ false
$ echo $?
1
Cの「同等」は次のとおりです。
false.c:
#include <stdlib.h> /* exit */
int main() {
exit(1);
}
bash.c:
#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */
int main() {
if (fork() == 0) {
/* Call false. */
execl("./false", "./false", (char *)NULL);
}
int status;
/* Wait for a child to finish. */
wait(&status);
/* Status encodes multiple fields,
* we need WEXITSTATUS to get the exit status:
* http://stackoverflow.com/questions/3659616/returning-exit-code-from-child
**/
printf("$? = %d\n", WEXITSTATUS(status));
}
Bashでは、Enterキーを押すと、上記のようにfork + exec + waitが発生し、bashは$?
をforkされたプロセスの終了ステータスに設定します。
注:echo
などの組み込みコマンドの場合、プロセスを生成する必要はなく、Bashは$?
を0に設定するだけで外部プロセスをシミュレートします。
標準とドキュメント
POSIX 7 2.5.2 "特殊パラメーター" http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :
?最新のパイプラインの10進終了ステータスに展開します(パイプラインを参照)。
man bash
「特別なパラメーター」:
シェルはいくつかのパラメーターを特別に扱います。これらのパラメーターは参照のみ可能です。それらへの割り当ては許可されていません。 [...]
?最後に実行されたフォアグラウンドパイプラインの終了ステータスに展開します。
ANSI CおよびPOSIXは、次のことを推奨します。
0
は、プログラムが成功したことを意味します
他の値:プログラムはなんとか失敗しました。
正確な値は、障害のタイプを示している可能性があります。
ANSI Cは値の意味を定義せず、POSIXは125より大きい値を指定します: 「POSIX」の意味は何ですか?
Bashはif
の終了ステータスを使用します
Bashでは、次のように、終了ステータス$?
を暗黙的に使用してif
ステートメントを制御します。
if true; then
:
fi
true
は、0を返すだけのプログラムです。
上記は次と同等です:
true
result=$?
if [ $result = 0 ]; then
:
fi
そして:
if [ 1 = 1 ]; then
:
fi
[
は奇妙な名前(およびそのように動作するBashビルトイン)を持つ単なるプログラムであり、1 = 1 ]
その引数も参照してください。 単一および二重の正方形の違いBashの括弧
$?最後に実行されたコマンドの結果(終了コード)です。
$?
は、一連のコマンドをデイジーチェーン接続できるように、コマンドの終了ステータスです。
例
command1 && command2 && command3
command2
command1's
がsuccess (0)
を生成する場合、$?
が実行され、command3
の$?
がsuccess
を生成する場合、command2
が実行されます
最後に実行されたコマンドの返されたエラーコードです。 0 =成功
set -e
が使用されている場合にスクリプトが終了する場合のデバッグに適しています。たとえば、コマンドの後にecho $?
を置いて終了させ、返されたエラー値を確認します。
最後のコマンドの終了コードが実行されました。