このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。
Linuxコマンドの基本:シェルスクリプトのコマンドと終了ステータス

シェルスクリプトのコマンドと終了ステータス
シェルスクリプトを理解する上で、コマンドの終了ステータスは非常に重要な概念です。if 文はコマンドの結果を基に条件分岐を行いますが、その際にコマンドの終了ステータスを利用します。ここでは、コマンドの終了ステータスとは何か、そしてそれをどのように if 文で活用するかを詳しく解説します。

コマンドの構造と終了ステータス
まず、以下の if 文の例を見てみましょう。
if [ "$1" = "ok" ]; then
# 処理
fi
この構造を分解すると、次のようになります。
- コマンド:
[ - 引数1:
"$1" - 引数2:
= - 引数3:
"ok" - 引数4:
]
if の後には コマンド があり、そのコマンドの実行結果(終了ステータス)に応じて条件分岐が行われます。
終了ステータスとは
Linux のコマンド(ls や grep など)は、実行後に終了ステータスと呼ばれる整数値を返します。この値は、特殊なシェル変数 $? を使って取得できます。
- 正常終了:終了ステータスは
0 - エラー終了:終了ステータスは
0以外の値
終了ステータスの確認例
ls コマンドの終了ステータスを確認
user01@ubuntu:~$ ls
bin ダウンロード ドキュメント ミュージック
snap テンプレート ビデオ 公開
work デスクトップ ピクチャ
user01@ubuntu:~$ echo $?
0 # 終了ステータスは 0(正常終了)lsコマンドが正常に実行されたため、終了ステータスは0です。
存在しないディレクトリを指定した場合
user01@ubuntu:~$ ls /non_exist_dir
ls: cannot access '/non_exist_dir': No such file or directory
user01@ubuntu:~$ echo $?
2 # 終了ステータスは 2(エラー終了)- 存在しないディレクトリを指定したため、
lsコマンドはエラーとなり、終了ステータスは2になります。
終了ステータスを表示するシェルスクリプトの作成
ステップ1:status-disp.sh の作成
user01@ubuntu:~$ nano status-disp.shstatus-disp.sh の内容
#!/bin/bash
ls /
echo "exit status = $?"
ls /non_exist_dir
echo "exit status = $?"解説
ls /:ルートディレクトリの内容を表示します。echo "exit status = $?":直前のコマンドの終了ステータスを表示します。ls /non_exist_dir:存在しないディレクトリを指定してエラーを発生させます。- 再度、終了ステータスを表示します。
ステップ2:実行権限の付与
user01@ubuntu:~$ chmod +x status-disp.shステップ3:スクリプトの実行
user01@ubuntu:~$ ./status-disp.sh出力結果
bin boot dev etc home lib ...
(ルートディレクトリの内容が表示される)
exit status = 0
ls: cannot access '/non_exist_dir': No such file or directory
exit status = 2解説
- 最初の
ls /は成功しているため、終了ステータスは0。 - 次の
ls /non_exist_dirは失敗しているため、終了ステータスは2。
if 文と終了ステータスの関係
if 文では、コマンドの終了ステータスを利用して条件分岐を行います。
- 終了ステータスが
0:条件は真と判断され、thenブロックが実行されます。 - 終了ステータスが
0以外:条件は偽と判断され、elseブロックが実行されます。
if 文の仕組み
if コマンド; then
# コマンドの終了ステータスが 0(真)の場合の処理
else
# コマンドの終了ステータスが 0 以外(偽)の場合の処理
fi
[ ] コマンドの実行と終了ステータス
[ ] はシェルの組み込みコマンドで、条件式を評価します。条件が真の場合は終了ステータス 0 を返し、偽の場合は 0 以外の値を返します。
例:条件式をコマンドとして実行
user01@ubuntu:~$ [ "$1" = "ok" ]
user01@ubuntu:~$ echo $?
1 # 引数がないため、条件は偽となり、終了ステータスは 1$1が"ok"でないため、条件は偽となります。
if 文でのコマンドの活用例
if 文の条件部分には、任意のコマンドを置くことができます。その終了ステータスによって、処理を分岐させます。
例:grep コマンドを使用した条件分岐
ステップ1:found-root.sh の作成
user01@ubuntu:~$ nano found-root.shfound-root.sh の内容
#!/bin/bash
if grep -q 'root' /etc/passwd; then
echo 'root found'
fi解説
grep -q 'root' /etc/passwd:/etc/passwdファイル内に'root'が含まれているかを検索します。-qオプションは出力を抑制し、終了ステータスのみを利用します。- 条件が真(
rootが見つかった)場合、echo 'root found'を実行します。
ステップ2:実行権限の付与
user01@ubuntu:~$ chmod +x found-root.shステップ3:スクリプトの実行
user01@ubuntu:~$ ./found-root.sh
root found解説
/etc/passwdにrootが含まれているため、grepコマンドの終了ステータスは0。- したがって、
if文の条件は真となり、echo 'root found'が実行されます。
コマンドの終了ステータスを利用するポイント
grep -qのようなオプション:-qオプションは出力を抑制し、終了ステータスのみを利用する場合に便利です。- 他のコマンドでも同様:
testコマンドやファイル検査演算子(-e、-d、-fなど)を使って条件を評価できます。
不要となったファイルの削除
user01@ubuntu:~$ rm status-disp.sh found-root.shまとめ
- 終了ステータス:コマンドが正常に終了したかどうかを示す数値。
0が正常終了、0以外がエラー。 $?シェル変数:直前に実行したコマンドの終了ステータスを格納。if文の条件:コマンドの終了ステータスを利用して、条件分岐を行う。[ ]コマンド:条件式を評価し、終了ステータスを返す組み込みコマンド。- 任意のコマンドを条件に使用可能:
grepやtestなど、終了ステータスを返すコマンドを活用して柔軟な条件分岐が可能。
これらの知識を活用して、シェルスクリプトでより高度な制御構造を実装し、効率的なスクリプトを作成していきましょう。
