こんにちは、Reoです。
現在はフリーランスのインフラエンジニアとして働きながら、インフラ特化の学習サービス「InfraDojo(インフラ道場)」を運営しています。
Linuxでコマンドを実行したあと、
「何も表示されなかったけど、成功したの?」
「前の処理が失敗したら、次の処理を止めたい」
と思ったことはありませんか?
そんなときに使うのが、終了ステータスです。
今回は、練習用ファイルを使いながら、次の3つを確認します。
-
$?で直前のコマンドの結果を確認する -
&&で、成功したときだけ次のコマンドを実行する -
||で、成功しなかったときに別のコマンドを実行する
1. 終了ステータスとは?
終了ステータスは、コマンドが処理を終えたときに返す数値です。
Bashでは、基本的に次のように扱います。
| 終了ステータス | シェルでの扱い |
|---|---|
0 |
成功 |
0以外 |
成功以外。条件分岐では偽として扱う |
直前のコマンドの終了ステータスは、$?で参照できます。参考:Bash公式ドキュメント「Exit Status」
確認するときは、次のように入力します。
echo $?
ただし、0以外の数値が何を意味するかは、コマンドによって異なります。
例えば、grepは検索条件に一致する行がない場合にも1を返します。数値だけを見て「システムが故障した」と判断するものではありません。
まずは、画面の表示とは別に、処理の結果を数値で確認できることを押さえましょう。
2. 練習用のファイルを準備する
この記事ではBashを使います。Bashが利用できる環境で、次を実行してください。
bash
以降は、同じターミナルで順番に操作します。管理者権限は不要です。
まず、練習用の一時ディレクトリを作り、そこへ移動します。
practice_dir=$(mktemp -d) && cd "$practice_dir"
ここにも&&が使われています。
意味は、「一時ディレクトリの作成と変数への代入が成功したら、そこへ移動する」です。
エラーが出ていなければ、練習用ファイルを作成します。
printf '%s\n' 'Linux practice' > sample.txt
これで、sample.txtに1行の文字列が保存されました。
3. $?で、成功した場合の結果を確認する
作成したファイルを読みます。
cat sample.txt
出力:
Linux practice
続けて、すぐに次を実行してください。
echo $?
出力:
0
catがファイルを読み込み、正常に終了したことを確認できました。
ここで大切なのは、確認したいコマンドの直後に$?を見ることです。
例えば、途中でpwdを実行してからecho $?を実行すると、確認できるのはpwdの終了ステータスになります。
cat sample.txt
pwd
echo $?
この最後の$?は、catの結果ではありません。
4. 存在しないファイルを指定してみる
次は、今回作成していないファイルを読み込もうとしてみます。
cat missing.txt
英語表示の環境では、例えば次のエラーが表示されます。
cat: missing.txt: No such file or directory
直後に、終了ステータスを確認します。
echo $?
一般的なLinux環境のcatでは、この例で次の値になります。
1
ファイルを読み込めず、成功以外の終了ステータスが返りました。
ただし、1という数字だけでは、原因を詳しく特定できません。
今回なら、エラーメッセージも合わせて読むことで、「指定したファイルが見つからなかった」と分かります。
終了ステータスで結果を確認し、メッセージで理由を調べる。
この2つを組み合わせて見ていきましょう。
5. &&は、成功したときだけ次を実行する
&&を使うと、左側のコマンドが成功した場合にだけ、右側のコマンドを実行できます。
cat sample.txt && printf '%s\n' '読み込み成功'
出力:
Linux practice
読み込み成功
cat sample.txtが終了ステータス0で終わったため、右側のprintfも実行されました。
今度は、存在しないファイルで試します。
cat missing.txt && printf '%s\n' '読み込み成功'
この場合は、catのエラーメッセージが表示されますが、「読み込み成功」は表示されません。
左側が成功していないため、右側は実行されないからです。
左側が成功
→ 右側を実行する
左側が成功以外
→ 右側を実行しない
「準備ができたら次の処理へ進む」という場面で使える書き方です。
6. ||は、成功しなかったときに次を実行する
||は、左側のコマンドが0以外で終了した場合に、右側のコマンドを実行します。
cat missing.txt || printf '%s\n' 'ファイルを読み込めませんでした'
表示例:
cat: missing.txt: No such file or directory
ファイルを読み込めませんでした
今回はcatが成功しなかったため、右側のメッセージ表示が実行されました。
存在するファイルでは、どうなるでしょうか。
cat sample.txt || printf '%s\n' 'ファイルを読み込めませんでした'
出力:
Linux practice
左側が成功したため、右側は実行されません。
&&と||を整理すると、次のとおりです。参考:Bash公式ドキュメント「Lists of Commands」
| 書き方 | 右側が実行される条件 |
|---|---|
コマンド1 && コマンド2 |
コマンド1の終了ステータスが0
|
| `コマンド1 |
7. セミコロンでつなぐ場合との違い
コマンドを;でつなぐ書き方もあります。
cat missing.txt; printf '%s\n' '次のコマンドを実行しました'
通常の設定では、次のようになります。
cat: missing.txt: No such file or directory
次のコマンドを実行しました
;は、左側のコマンドが終了したあと、成功・失敗にかかわらず右側を実行します。
そのため、次の2つは意味が異なります。
cat missing.txt && printf '%s\n' '次の処理'
cat missing.txt; printf '%s\n' '次の処理'
| 記号 | 基本的な動作 |
|---|---|
&& |
左側が成功したら、右側を実行 |
| ` | |
; |
左側が終わったら、右側を実行 |
ここでは、set -eなどによる終了制御を追加していないBashを想定しています。
手順をつなげるときは、前の処理が失敗しても、次を実行してよいかを考えて記号を選びましょう。
8. あとから使う結果は、変数へ保存する
終了ステータスを確認したあと、別の処理でも使いたいことがあります。
その場合は、直後に変数へ保存します。
cat missing.txt
practice_status=$?
保存した値を表示します。
printf '終了ステータス: %s\n' "$practice_status"
出力例:
終了ステータス: 1
こうしておけば、別のコマンドを実行しても、保存した値を参照できます。
また、次のように||の右側まで実行されたあとでは、
cat missing.txt || printf '%s\n' '読み込み失敗'
その直後の$?は、最後に実行したprintfの結果になります。printfが成功すれば0です。
複数のコマンドをつないだあとは、どのコマンドが最後に実行されたかにも注意してください。
練習が終わったら、最初に起動したBashを終了します。
exit
コマンドを入力したあと、結果まで確認しよう
今回は、次の違いを確認しました。
-
$?:直前の終了ステータスを参照する -
&&:成功したときだけ次を実行する -
||:成功しなかったときに次を実行する -
;:通常は成功・失敗にかかわらず順番に実行する
コマンドは、入力して終わりではありません。
「何が表示されたか」
「どんな終了ステータスだったか」
「次の処理は実行されたか」
まで確認すると、手順やシェルスクリプトの動きを追いやすくなります。
自分が運営するInfraDojo(インフラ道場)では、ブラウザ上の学習用シミュレーターで、課題を読み、コマンドを入力し、結果を確認しながらLinuxの基本操作を学べます。
環境構築不要で、無料の入門コースから取り組めます。
▼ InfraDojo(インフラ道場)