Bash特殊構文・特殊変数・特殊展開の完全ガイド

概要

本記事では、Bashシェルで使用される全ての特殊構文・特殊変数・展開ルール・制御構文を体系的にまとめます。


変数表記について

動的・環境依存な値は <<変数名>> として表記し、全ての使用例を明示します。

変数名 説明
<<var>> name, path, user 任意の変数名
<<default>> guest, 8080 デフォルト値や代替値
<<pattern>> *.txt, */ ファイル名や文字列パターン
<<offset>> 0, 3 部分文字列の開始位置(0始まり)
<<length>> 4, 10 部分文字列の長さ
<<prefix>> ENV_, HOST 変数名の先頭部分一致
<<index>> 0, 1, 2 配列や連想配列のインデックス(キー)
<<file>> /tmp/test.txt ファイルパス

Step 1: 特殊記号(メタキャラクタ)

記号 意味 使用例
* 任意の文字列にマッチ ls *.txt → すべての .txt を一覧
? 任意の1文字にマッチ ls ?.sha.sh, b.sh など
[a-z] 範囲指定マッチ ls [A-Z]* → 大文字で始まるファイル
{a,b} ブレース展開 mv {hoge,huga}
{1..3} 連番展開 touch file{1..3}.txtfile1.txt file2.txt file3.txt
$ 変数展開 echo $HOME
!(否定) 条件否定演算子 [[ ! -f test.txt ]] → ファイルが存在しなければ真
!(ヒストリー展開) コマンド履歴展開 !10 → 履歴番号10のコマンドを再実行
~ ホームディレクトリ展開 cd ~
; コマンド連結 pwd; ls
&& 成功時のみ実行 make && echo OK
` `
& バックグラウンド実行 sleep 5 &
` ` パイプ
> 標準出力リダイレクト echo hi > out.txt
>> 出力を追記 echo hi >> out.txt
< 標準入力を指定 wc -l < file.txt
() サブシェル実行 (cd /tmp; ls)
{} 同一シェル内実行 { echo A; echo B; }
\ エスケープ echo \$HOME
' ' リテラル(展開なし) echo '$USER'
" " 展開あり echo "$USER"

Step 2: 特殊変数

変数 内容 使用例
$0 スクリプト名 echo $0script.sh
$1〜$9 引数 echo $1
$@ 引数配列展開 for a in "$@"; do echo $a; done
$# 引数の数 echo $#
$? 直前の終了コード ls /nope; echo $?
$$ 現在プロセスID echo $$
$! 最後のBGジョブPID sleep 10 & echo $!
$- 現在のシェルオプション echo $-
$_ 直前コマンドの最後の引数 echo $_
$PPID 親プロセスID echo $PPID
$RANDOM 乱数0–32767 echo $RANDOM
$SECONDS シェル開始からの秒数 echo $SECONDS
$FUNCNAME 関数名 myf(){ echo $FUNCNAME; }; myf
$PIPESTATUS[@] パイプ中コマンドの終了コード `ls

Step 3: 変数展開(Parameter Expansion)

構文 意味 使用例
${<<var>>} 変数展開 name=user; echo ${name}
${<<var>>:-<<default>>} 未定義ならdefault使用 echo ${user:-guest}
${<<var>>:=<<default>>} 未定義なら代入 echo ${port:=8080}
${<<var>>:+alt} 定義済みならalt使用 x=1; echo ${x:+OK}
${<<var>>:?msg} 未定義ならエラー echo ${config:?config missing}
${#<<var>>} 文字列長 name=user; echo ${#name}
${<<var>>%<<pattern>>} 末尾最短削除 path=/a/b/c; echo ${path%/*}/a/b
${<<var>>%%<<pattern>>} 末尾最長削除 echo ${path%%/*} → 空
${<<var>>#<<pattern>>} 先頭最短削除 echo ${path#*/}a/b/c
${<<var>>##<<pattern>>} 先頭最長削除 echo ${path##*/}c
${<<var>>/<<pattern>>/<<repl>>} 最初の一致置換 echo ${msg/foo/bar}
${<<var>>//<<pattern>>/<<repl>>} 全一致置換 echo ${msg// /_}
${<<var>>:<<offset>>} offsetから末尾まで s=abcdef; echo ${s:2}cdef
${<<var>>:<<offset>>:<<length>>} offsetからlength分 echo ${s:1:3}bcd
${!<<prefix>>*} prefixで始まる変数一覧 HOST1=x; HOST2=y; echo ${!HOST*}
${!<<var>>} 間接参照 ref=NAME; NAME=user; echo ${!ref}
${<<var>>,} / ${<<var>>^^} 大文字・小文字変換 n=abc; echo ${n^^}ABC
${<<var>>@Q} 引用付き展開 x='abc'; echo ${x@Q}'abc'

Step 4: 配列・連想配列

# 配列の定義と利用
arr=(a b c)
echo ${arr[<<index>>]}        # 指定インデックス要素を取得
echo ${#arr[@]}               # 配列要素数
for i in "${arr[@]}"; do echo $i; done

# 連想配列の定義と利用
declare -A map
map[<<index>>]=100
map[name]=user
echo ${map[<<index>>]}        # 値取得
echo ${!map[@]}               # すべてのキー一覧

Step 5: 算術展開

x=5
y=3
echo $((x + y))    # 8
((x *= 2))
echo $x            # 10

Step 6: 条件式と比較

# 文字列
if [ "$USER" = "root" ]; then echo root; fi

# 数値
if [ "$x" -lt 10 ]; then echo "small"; fi

# ファイル
if [ -f /etc/passwd ]; then echo "exists"; fi

# 正規表現
s="hello123"
[[ $s =~ [0-9]+ ]] && echo "contains number"

Step 7: コマンド置換・サブシェル

# コマンド出力を展開
echo "Today: $(date +%Y-%m-%d)"

# サブシェル
(cd /tmp; ls)

Step 8: リダイレクト・FD操作

echo "Hello" > <<file>>         # 標準出力をファイルに
echo "Append" >> <<file>>       # 追記
wc -l < <<file>>                # 標準入力として使う
ls /notfound 2> err.log         # 標準エラー出力をファイルへ
echo "OK" >&2                   # 標準エラー出力に送る
exec 3> custom.log              # FD3を開く
echo "via fd3" >&3
exec 3>&-                       # FD3を閉じる

用語補足: ファイルディスクリプタ(FD)

FD番号 名称 説明 使用例
0 標準入力(stdin) キーボードやファイルからの入力 < file.txt
1 標準出力(stdout) 通常の出力(端末・ファイル) echo test > out.txt
2 標準エラー出力(stderr) エラー出力専用 ls /nope 2> err.log
3以降 任意のFD ユーザー定義の出力ストリーム exec 3> log.txt

FD3 とは、ユーザーが自由に作成できる追加のファイルディスクリプタです。
例えば次のように使います:

exec 3> process.log   # FD3を作成
echo "実行開始" >&3   # FD3に書き込む → process.logに出力
exec 3>&-             # FD3を閉じる

Step 9: トラップとエラー制御

set -e                # エラーで停止
set -u                # 未定義変数をエラー扱い
set -x                # 実行コマンドを表示
set -o pipefail       # パイプ途中のエラー検出

trap 'echo 終了しました' EXIT
trap 'echo エラー発生' ERR

Step 10: ジョブ制御

sleep 10 &           # バックグラウンドで実行(ジョブ1)
jobs                 # ジョブ一覧表示
fg %1                # ジョブ番号1をフォアグラウンドへ
bg %1                # ジョブ番号1をバックグラウンドへ
disown %1            # ジョブ1をシェル管理から切り離す
kill %1              # ジョブ1を終了

用語補足: ジョブ番号と %1 の意味

Bashで & をつけてコマンドを実行すると、それは「ジョブ」として管理されます。
jobs コマンドを実行すると、シェル内で実行中のジョブ一覧が表示されます。

例:

sleep 60 &
jobs

出力:

[1]+  Running  sleep 60 &
  • [1]ジョブ番号
  • %1 は「ジョブ番号1番を参照する記号」
記号 意味
%1 ジョブ番号1番のジョブ
%+ 現在のカレントジョブ
%- 直前のジョブ

使用例:

fg %1    # ジョブ1をフォアグラウンドへ
bg %1    # ジョブ1をバックグラウンド再開
kill %1  # ジョブ1を終了

Step 11: 特殊コマンド・予約語

:               # 何もしない(常に成功)
true            # 成功終了
false           # 失敗終了
source ~/.bashrc
eval "echo executed"
{ echo A; echo B; }

まとめ

Bashスクリプトにおける特殊構文・展開・変数・記号・制御構文を包括的に網羅しました。
これを理解すれば、任意のシェルスクリプトを正確に解析・設計でき、再利用性と安全性の高い自動化が実現できます。