Woman typing on a laptop
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 "hello" sample.txt
echo $?
0
: 一致する行が見つかった1
: 一致する行が見つからなかった2
: エラー(ファイルがない、パーミッションエラーなど)[ -f "file.txt" ]
echo $?
0
: 条件が真1
: 条件が偽ping -c 1 8.8.8.8
echo $?
0
: 接続成功1
以上: 接続失敗やその他のエラーこのように、コマンドによって終了ステータスの持つ意味は若干異なります。スクリプトを書く際は、それぞれのコマンドのマニュアル(man コマンド名
)を確認することが重要です。
スクリプトを書くときに「$?」は非常に有用です。以下はその一例です。
#!/bin/bash
cp /etc/hosts /backup/
if [ $? -eq 0 ]; then
echo "バックアップ成功:$(date)" >> backup.log
else
echo "バックアップ失敗:$(date)" >> backup.log
fi
このスクリプトでは、cp
コマンドの成否によってログの内容を変えています。
#!/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 [ $? -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操作やスクリプト作成に役立ててください。