Categories: linux

【Linux初心者向け】「$?」コマンドで直前のコマンドの終了ステータスを確認する方法と活用術

Linuxコマンドを使って作業をしていると、「コマンドが成功したのか失敗したのか」を知りたい場面が出てきます。特にシェルスクリプトを書く時や複数のコマンドを連続して実行する場面では、その判断が処理の流れを左右します。
そんな時に使えるのが、「$?」という特殊変数です。これは直前に実行したコマンドの終了ステータス(終了コード)を確認するためのもので、スクリプトや自動化の現場では非常に重宝されます。
この記事では「$?」の基本から、実用的な使い方、応用例まで、Linux初心者にも分かりやすく解説していきます。


「$?」とは何か?基本の意味と仕組み

「$?」は、BashやZshなどのシェル環境で使える**特殊変数(特殊パラメータ)**です。これは「直前に実行されたコマンドの終了ステータス(exit status)」を数値で返します。

この数値は以下のような意味を持ちます。

  • 0: コマンドが正常に終了した(成功)
  • 0以外: 何らかのエラーや異常が発生した(失敗)

たとえば、次のように使います。

ls /etc
echo $? # -> 0 (成功)

ls /not_exist_directory
echo $? # -> 2 (失敗)

このように、「$?」はコマンドの成否を即座に数値で確認できる便利な仕組みなのです。


終了ステータスは何のためにあるのか?

終了ステータスは、主にエラーハンドリングや条件分岐の判断材料として使われます。たとえば、シェルスクリプトでは次のように記述することで、処理の流れを制御できます。

cp file1.txt backup/
if [ $? -eq 0 ]; then
echo "バックアップ成功"
else
echo "バックアップ失敗"
fi

このようにして、「成功した時だけ次の処理に進む」といったロジックを簡単に組むことができます。

また、終了ステータスはUNIX/Linuxにおいて「コマンドが何をしたか」をプログラム間で伝えるためのインタフェースでもあります。他のプロセスに結果を知らせる手段としても重要です。


さまざまなコマンドでの終了ステータスの違い

コマンドによっては、終了ステータスが0や1だけではなく、複数のパターンを持つものもあります。以下はその一例です。

grepコマンド

grep "hello" sample.txt
echo $?
  • 0: 一致する行が見つかった
  • 1: 一致する行が見つからなかった
  • 2: エラー(ファイルがない、パーミッションエラーなど)

testコマンド([ … ]構文)

[ -f "file.txt" ]
echo $?
  • 0: 条件が真
  • 1: 条件が偽

pingコマンド(一部のLinuxディストリビューションではsudoが必要)

ping -c 1 8.8.8.8
echo $?
  • 0: 接続成功
  • 1 以上: 接続失敗やその他のエラー

このように、コマンドによって終了ステータスの持つ意味は若干異なります。スクリプトを書く際は、それぞれのコマンドのマニュアル(man コマンド名)を確認することが重要です。


スクリプトにおける「$?」の活用例

スクリプトを書くときに「$?」は非常に有用です。以下はその一例です。

例1:バックアップ処理とログ出力

#!/bin/bash

cp /etc/hosts /backup/
if [ $? -eq 0 ]; then
echo "バックアップ成功:$(date)" >> backup.log
else
echo "バックアップ失敗:$(date)" >> backup.log
fi

このスクリプトでは、cpコマンドの成否によってログの内容を変えています。

例2:複数ステップの処理確認

#!/bin/bash

mkdir temp_dir
if [ $? -ne 0 ]; then
echo "ディレクトリ作成に失敗しました"
exit 1
fi

cd temp_dir
if [ $? -ne 0 ]; then
echo "ディレクトリ移動に失敗しました"
exit 1
fi

echo "作業ディレクトリに移動しました"

各ステップごとに「$?」でエラーを検出し、適切に終了させることで、安全な処理が実現できます。


「$?」とよく組み合わせるコマンドや構文

if文との組み合わせ

もっとも基本的な使い方です。

if [ $? -eq 0 ]; then
echo "成功"
fi

&& や || の構文

これらは「成功したら次」「失敗したら次」といった形で処理を続ける便利な書き方です。

mkdir newdir && echo "作成成功" || echo "作成失敗"

この場合、mkdirが成功すれば「作成成功」が出力され、失敗すれば「作成失敗」が出力されます。実はこの構文の裏側では「$?」による判定が使われています。


よくある注意点と落とし穴

「$?」は直前のコマンドの結果のみを返す

例えば、次のようにすると意図通りの結果にならないことがあります。

ls nofile.txt
echo "確認中..."
echo $? # これはechoの終了ステータスを出してしまう!

この場合、lsが失敗しても、echo "確認中..." が成功していれば $? は0になります。
すぐにチェックしないと正しい結果が得られないというのは、初心者がよくハマるポイントです。

パイプライン中の「$?」には注意

cat sample.txt | grep "test"
echo $?

この場合の「$?」は最後のコマンド(ここではgrep)の結果を示します。catのエラーは無視されるため、すべてのステータスを見たいときにはPIPESTATUS変数を使う必要があります。

echo "${PIPESTATUS[@]}"

まとめ:「$?」を使いこなして、Linuxスキルを一歩前進させよう

「$?」は小さな記号ですが、Linuxの世界では非常に重要な意味を持ちます。コマンドやスクリプトが成功したのかどうか、エラーが出ていたのかを即座に判定できる便利なツールです。特にシェルスクリプトを書く場面では、この終了ステータスを活用することで、安全で柔軟な処理フローを構築できます。

慣れてくると、$?は自然と手が動くようになるほど便利な存在です。ぜひ本記事を参考に、あなたのLinux操作やスクリプト作成に役立ててください。

upandup

Web制作の記事を中心に、暮らし、ビジネスに役立つ情報を発信します。 アフィリエイトにも参加しています。よろしくお願いいたします。