【Shell Script】変数の使い方:宣言・展開・クォーティング

Shell Script

こんにちは、かつコーチです。

前回は、シェバンと実行権限というスクリプトを「動かす」ための土台を解説しました。

今回からは、スクリプトの中身をより実用的にしていく回として、変数の使い方を扱います。

変数を使いこなせるようになると、同じスクリプトでも扱える処理の幅が一気に広がります。

つまずきやすいクォーティングの落とし穴も含めて、しっかり押さえていきましょう。

変数とは?

変数:値を入れておくラベル付きの箱

変数とは、文字列や数値などの値を一時的に保存しておく「ラベル付きの箱」のようなものです。

箱に「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つの単語(reportfinal.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, 初心者向け, 入門

タイトルとURLをコピーしました