こんにちは、かつコーチです。
前回は、シェバンと実行権限というスクリプトを「動かす」ための土台を解説しました。
今回からは、スクリプトの中身をより実用的にしていく回として、変数の使い方を扱います。
変数を使いこなせるようになると、同じスクリプトでも扱える処理の幅が一気に広がります。
つまずきやすいクォーティングの落とし穴も含めて、しっかり押さえていきましょう。
変数とは?
変数:値を入れておくラベル付きの箱
変数とは、文字列や数値などの値を一時的に保存しておく「ラベル付きの箱」のようなものです。
箱に「name」というラベルを貼っておけば、後から「nameの中身は?」と聞くだけで、入れた値を取り出せます。
シェルスクリプトでは、この箱の中身をコマンドの結果や設定値として使い回すことで、柔軟な処理を組み立てられます。
なぜ変数が必要なのか
もし変数がなければ、同じ値(例えばバックアップ先のディレクトリパス)を何度も直接書き込むことになり、変更のたびに全箇所を修正する羽目になります。
変数に入れておけば、修正箇所は1か所で済み、書き間違いのリスクも減らせます。
基本の書き方
変数の宣言:イコールの前後にスペースを入れない
シェルスクリプトの変数宣言は、次のように書きます。
#!/bin/bash
name="かつコーチ"
count=3
echo "$name さん、あと $count 回です"
かつコーチ さん、あと 3 回です
ここで重要なのが、name="かつコーチ"のようにイコールの前後にスペースを入れないことです。
他のプログラミング言語に慣れていると、ついname = "かつコーチ"と書きたくなりますが、シェルではスペースがあるとエラーになります。
変数の展開:$を付けて中身を取り出す
箱の中身を取り出す(展開する)には、変数名の前に$を付けます。
backup_dir="/var/backup"
echo "保存先は $backup_dir です"
$backup_dirと書いた部分が、実行時に実際の値(/var/backup)に置き換わります。
変数名の範囲を明確にしたい場合は、${backup_dir}のように波かっこで囲む書き方も使われます。
echo "${backup_dir}_old"
# → /var/backup_old
波かっこを使わないと$backup_dir_oldが1つの変数名として誤認識されてしまうため、他の文字列と直接つなげる場面では特に有効です。
コマンドの実行結果を変数に入れる
コマンドの実行結果を変数に保存するには、$( )(コマンド置換)を使います。
today=$(date +%Y-%m-%d)
echo "今日は $today です"
今日は 2026-09-08 です
dateコマンドの出力結果が、そのままtoday変数に格納されているのが分かります。
よくあるつまずきポイント:クォート漏れでファイル名が壊れた話
私が実際にバックアップスクリプトを書いていたとき、ファイル名にスペースが含まれるケースを想定しておらず、次のようなトラブルに遭遇しました。
❌ Before:変数をダブルクォートで囲まずに使う
filename="report final.txt"
cp $filename /backup/
cp: cannot stat 'report': No such file or directory
cp: cannot stat 'final.txt': No such file or directory
原因は、クォートなしで展開された$filenameが、シェルによってスペースの位置で2つの単語(reportとfinal.txt)に分割(単語分割)されてしまったことでした。
1つのファイル名のつもりが、シェルには2つの引数として渡ってしまったのです。
✅ After:変数をダブルクォートで囲む
filename="report final.txt"
cp "$filename" /backup/
"$filename"のようにダブルクォートで囲むことで、スペースを含めた中身がそのまま1つの値として扱われ、正しくコピーできるようになります。
このトラブル以来、私は「変数展開には基本的にダブルクォートを付ける」ことをルール化しています。
応用・一歩先の使い方
シングルクォートとダブルクォートの違い
クォートには、展開の可否という重要な違いがあります。
name="かつコーチ"
echo "こんにちは $name" # → こんにちは かつコーチ(展開される)
echo 'こんにちは $name' # → こんにちは $name(展開されない)
ダブルクォート(")は変数展開を行い、シングルクォート(')は文字列をそのまま扱います。
「変数を含めたいときはダブル、文字列そのままの意味で使いたいときはシングル」と使い分けると、意図しない展開ミスを防げます。
読み取り専用変数(readonly)
値を書き換えられたくない変数には、readonlyを付けられます。
readonly max_retry=3
max_retry=5
bash: max_retry: readonly variable
設定値のように途中で変わってほしくない変数には、こうした保護も有効です。
まとめ
この記事のポイント
- 変数は値を入れておくラベル付きの箱で、
name=値で宣言し、$nameで取り出す - イコールの前後にスペースを入れない
- コマンドの実行結果は
$( )(コマンド置換)で変数に入れられる - 変数展開は基本的にダブルクォートで囲み、単語分割によるトラブルを防ぐ
次に読むべき記事
次回は、変数を使った条件分岐の基本として、if文の書き方を解説します。
→ 次の記事:if文で条件分岐する基本
タグ: Shell, 初心者向け, 入門