はじめに (対象読者・この記事でわかること)
この記事は、Bashスクリプトを書き始めたばかりの初心者~中級者の方を対象にしています。
「if文で数値比較しようとしたら、急に単項演算子が予期されますとか言われて意味が分からない」という経験がある方に最適です。
記事を読むことで、なぜそのエラーが出るのか、どうすれば確実に回避できるのか、そして今後同じ轍を踏まないためのコーディングルールまで、一連の流れを完全に把握できるようになります。
前提知識
- Bashで簡単なスクリプトを書いたことがある
- 変数に値を代入したことがある
- if文の存在を知っている
エラーの概要:「単項演算子が予期されます」とは何か
Bashで数値比較を行おうとした際に、以下のようなエラーメッセージが出力されることがあります。
[: 単項演算子が予期されます
このメッセージは、testコマンド([ はその短縮形)が「右辺が存在しない単項演算」として解釈してしまったときに発生します。
端的に言えば「比較対象の変数が空っぽで、演算できない」という状況です。
単項演算子エラーの原因と確実な修正方法
ステップ1:最小構成でエラーを再現する
まず、エラーが出やすい最小スクリプトを用意します。
Bash#!/usr/bin/env bash read -rp "数字を入力してください: " num if [ "$num" -eq 100 ]; then echo "100です" fi
このスクリプトを実行し、何も入力せずにEnterを押すと以下のエラーが出ます。
[: 単項演算子が予期されます
ステップ2:なぜ空文字になるとエラーになるのかを読み解く
Bashは変数の展開後、以下のように解釈します。
# $num が空の場合
[ -eq 100 ] # ← 左辺が空なので「単項演算子が足りない」というエラーに
-eq は二項演算子なので、左右に値が必須です。左が空だと文法的に破綻します。
ステップ3:防御的に書く=クォートで囲むだけでは不十分
変数をダブルクォートで囲んでも、空文字列は空文字列なのでエラーは変わりません。
Bashif [ "$num" -eq 100 ]; then # 空文字のままではエラー
そこで以下の二つの対策が有効です。
対策A:デフォルト値を与える
Bashif [ "${num:-0}" -eq 100 ]; then echo "100です" fi
:-0 は「num が未設定または空なら 0 を代わりに使う」という意味です。
対策B:数値チェックを事前に行う
Bashif [[ "$num" =~ ^[0-9]+$ && "$num" -eq 100 ]]; then echo "100です" fi
正規表現で数値であることを確認してから比較することで、空文字や文字列を排除できます。
対策C:算術展開に任せる
Bashif (( num == 100 )); then echo "100です" fi
(( )) は数値評価専用で、空文字でも 0 として扱われるため、単項演算子エラーが起きません。
ハマった点:set -u との組み合わせ
set -u(未設定変数の参照で即終了)を有効にしていると、空チェック前にスクリプトが終了してしまうことがあります。
その場合も対策Aのデフォルト値や対策Cの算術展開が有効です。
解決策:実用例を一つにまとめる
以下は、本番で使いやすい防御的スクリプトです。
Bash#!/usr/bin/env bash set -euo pipefail read -rp "数字を入力してください: " num # 空・数字チェック [[ "${num:-}" =~ ^[0-9]+$ ]] || { echo "数値を入力してください"; exit 1; } if (( num == 100 )); then echo "ピンポン!100です" else echo "残念、100ではありません" fi
まとめ
本記事では、「単項演算子が予期されます」というBash特有のエラーのメカニズムと、実践的な回避策を紹介しました。
- エラーの本質は「空文字を数値比較しようとした」こと
- デフォルト値、正規表現、算術展開の三種の神器で防げる
- 生の
[ではなく(( ))を使うとコードがシンプルになる
これらのテクニックを身につけることで、今後シェルスクリプトを書く際に「なんでまた急に文法エラー?」という時間を大幅に削減できます。次回は、set オプションを使った堅牢スクリプトの書き方を深掘りします。
参考資料
- Bash Reference Manual §6.5 Shell Arithmetic
- シェル・プログラミング実践書(株式会社オーム社)
- The Bash Hackers Wiki – Tests And Conditionals
