実践編:変数・パラメータ展開・配列
変数の宣言と環境変数のエクスポート、特殊変数、誤動作を防ぐクォーティング規則、高度なパラメータ展開、および配列の操作方法を解説します。
変数の定義とスコープ
Bash では変数名と代入値の間にイコール(=)を記述します。イコールの前後に半角スペースを入れてはいけません(スペースを入れるとコマンド名や引数として誤認されます)。
# 正しい代入
TARGET_ENV="production"
PORT=8080
# 誤り(エラーになります)
# TARGET_ENV = "production"
» シェル変数と環境変数(export)
通常の変数はそのシェルプロセス内でのみ有効な「シェル変数」です。子プロセス(起動したコマンドや別スクリプト)にも変数を引き継ぎたい場合は export コマンドで「環境変数」として宣言します。
export API_KEY="secret_key_12345"
特殊変数(自動設定変数)
Bash がスクリプト実行時やコマンド終了時に自動的に値を設定する組み込み変数です。
| 変数 | 内容 |
|---|---|
$0 | 実行中のスクリプト名またはシェルの名前 |
$1〜$9 | コマンドライン引数(第1引数〜第9引数) |
${10} 以降 | 10番目以降の引数は波括弧で囲む |
$# | 渡されたコマンドライン引数の総数 |
$@ | 全引数のリスト("$@" で各引数を安全に個別展開) |
$? | 直前のコマンドの終了ステータス(0 は成功、0 以外は失敗) |
$$ | 現在のシェルプロセスのプロセス ID(PID) |
$! | 直前にバックグラウンドで起動されたプロセスの PID |
クォーティングの原則
Bash スクリプトで最も不具合の原因になりやすいのがクォートの省略です。
- クォートなし: 空白による単語分割(Word Splitting)やワイルドカード展開(Globbing)が発生します。ファイル名にスペースが含まれているとコマンドが分割され、意図しない挙動になります。
- シングルクォート(
'...'): 内部のすべての文字を純粋な文字列として扱います。変数やコマンド置換は一切展開されません。 - ダブルクォート(
"..."): 変数展開やコマンド置換を許可しつつ、スペースによる単語分割を防ぎます。
安全なスクリプトを書くための基本ルールとして、変数を展開する際は常にダブルクォートで囲む("$var") ことを徹底します。
パラメータ展開(Parameter Expansion)
波括弧構文 ${...} を用いることで、外部コマンドを呼び出さずにシェル内部だけで高速に文字列加工を行えます。
» 既定値の指定と検証
# 変数が未設定または空の場合、指定した既定値を使用する
ENV_NAME="${ENV_TARGET:-development}"
# 変数が未設定の場合、エラーメッセージを表示してスクリプトを中断する
CONFIG_FILE="${APP_CONFIG:?Config path is required}"
» 文字列の切り取りと置換
FILENAME="archive-2026.tar.gz"
# 前方一致削除(最短マッチ: #、最長マッチ: ##)
echo "${FILENAME#*-}" # 2026.tar.gz
echo "${FILENAME##*.}" # gz(拡張子の抽出)
# 後方一致削除(最短マッチ: %、最長マッチ: %%)
echo "${FILENAME%.*}" # archive-2026.tar(拡張子の除去)
echo "${FILENAME%%-*}" # archive
# 文字列置換(最初の一致: /、すべての一致: //)
TEXT="apple banana apple"
echo "${TEXT/apple/orange}" # orange banana apple
echo "${TEXT//apple/orange}" # orange banana orange
配列の操作
複数の要素を順序付けて管理する配列の構文です。
» インデックス配列
# 配列の定義
SERVERS=("web01" "web02" "db01")
# 要素の参照(インデックスは 0 始まり)
echo "${SERVERS[0]}"
# 全要素を安全に展開(for ループ等で使用)
for s in "${SERVERS[@]}"; do
echo "Connecting to $s..."
done
# 要素数の取得
echo "Count: ${#SERVERS[@]}"
# 末尾に要素を追加
SERVERS+=("db02")
» 連想配列(ハッシュテーブル)
Bash 4.0 以降では、文字列をキーとする連想配列が利用可能です。使用前に declare -A で宣言する必要があります。
# 連想配列の宣言
declare -A PORT_MAP
PORT_MAP["http"]=80
PORT_MAP["https"]=443
PORT_MAP["ssh"]=22
echo "HTTPS port is: ${PORT_MAP["https"]}"