「バッククォートでコマンドの結果を埋め込みたいけど書き方を忘れた」
Bashで引用符を使い分けないと、変数が展開されたりされなかったりして思った通りに動かない場面が必ず出てきます。
この記事では、Bashの引用符(シングルクォート・ダブルクォート・バッククォート・ヒアドキュメント)の挙動を実例つきで整理します。コマンドラインだけでなくシェルスクリプトでも同じルールが効くので、一度ここで体に染み込ませてください。
この記事のポイント
・シングルクォート '...' は中身を「そのまま文字列」として扱う
・ダブルクォート "..." は変数 $VAR とコマンド置換を展開する
・バッククォート `cmd` と $(cmd) はコマンドの実行結果を埋め込む
・ヒアドキュメント <<EOF は複数行入力をまとめてコマンドに渡せる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
事前準備:実習用の環境変数を設定する
このあと出てくる引用符の動作を確認するため、実習用に環境変数DATE を設定しておきます。$ DATE=6月20日 $ echo $DATE 6月20日
DATE に「6月20日」が入りました。この変数を使って、引用符の種類ごとに挙動の違いを見ていきます。シングルクォート(単一引用符 ')はそのまま文字列として扱う
Bashで「'」(シングルクォート)で括った内容は、すべてそのままの文字列として扱われます。変数も特殊文字も解釈されず、書いた通りに出力されるのが最大の特徴です。
$ echo '$DATE' $DATE ← 変数として展開されず、リテラル文字列として表示される
$記号も普通の文字として扱われるため、変数 $DATE の中身(6月20日)ではなく、文字列「$DATE」がそのまま画面に出ます。シングルクォートを使う場面の代表例は次の3つです。
・パスワードや特殊文字(
$、!、*)を含む文字列をそのまま渡したい時・正規表現を
grep や sed に渡す時(シェルに先に解釈されたくない)・ファイル名にスペースや記号が含まれている時の安全な書き方
$ grep 'error.*timeout' /var/log/messages ← .* をシェルに先に展開されず、grepにそのまま渡せる
\' を挟む書き方になります。$ echo 'It'\''s OK' It's OK
ダブルクォート(二重引用符 ")は変数を展開する
「"」(ダブルクォート)で括った内容は、変数$VAR とコマンド置換 $(...)、バッククォート `...` だけが展開されます。それ以外の文字はそのまま文字列扱いです。$ echo "今日は$DATEです。" 今日は6月20日です。 ← $DATE の中身に展開される
$ echo '今日は$DATEです。' ← シングルクォート 今日は$DATEです。 ← 変数は展開されない $ echo "今日は$DATEです。" ← ダブルクォート 今日は6月20日です。 ← 変数が展開される
ダブルクォート内で変数展開を止めたい場合は \ でエスケープする
ダブルクォート内で「$記号は出したいが、変数として展開したくない」場合は、\(バックスラッシュ/日本語キーボードでは円記号¥)でエスケープします。$ echo "変数\$DATEの内容は「$DATE」" 変数$DATEの内容は「6月20日」 ↑ \$ はリテラルの $DATE として表示される ↑ $DATE は変数展開されて 6月20日 になる
表示上はバックスラッシュ
\ が円記号 ¥ として見えることがありますが、文字コード上は同じ(0x5C)で意味も同一です。詳しくは ¥記号を入力するとバックスラッシュになる理由 を参照してください。ダブルクォート内でエスケープが効く特殊文字
ダブルクォート内で\ によるエスケープが効くのは、次の文字に限られます。| 記号 | 意味 |
|---|---|
\$ |
$記号をそのまま表示(変数展開を抑止) |
\` |
バッククォートをそのまま表示(コマンド置換を抑止) |
\" |
ダブルクォートをそのまま表示 |
\\ |
バックスラッシュをそのまま表示 |
\n |
そのまま \n として表示される(改行にはならない) |
上記以外(例:
\a、\t)は、バックスラッシュごとそのまま出力されます。改行や水平タブを入れたい時は echo -e や printf を使ってください。バッククォート(` )はコマンドの実行結果を埋め込む
「`」(バッククォート/逆引用符)で囲んだ部分は、その中身がコマンドとして実行され、結果に置き換わります。これを「コマンド置換」と呼びます。$ echo "現在のディレクトリは`pwd`" ↑ バッククォートで pwd コマンドを括る 現在のディレクトリは/home/pakira ↑ pwd の実行結果が埋め込まれる
/home/pakira が、文字列の中にそのまま埋め込まれているのが分かります。$(コマンド) 形式はバッククォートのモダンな書き方
バッククォートと同じ「コマンド置換」を、$(コマンド) という書き方でも実現できます。POSIX標準で、現在のシェルスクリプトではこちらが推奨です。$ echo "現在のディレクトリは$(pwd)" 現在のディレクトリは/home/pakira $ FILE="log_$(date +%Y%m%d).txt" $ echo $FILE log_20250620.txt ← 変数代入の中でもコマンド置換が使える
` とドル+丸カッコ $() はどちらも同じ動きをしますが、$() のほうがネストできるという大きな利点があります。# バッククォートのネストはエスケープが必要で読みづらい $ echo "`echo \`date\``" # $() のネストはそのまま書ける $ echo "$(echo $(date))"
$() を使うのが安全です。バッククォートは古いスクリプトを読み書きする時の知識として押さえておけば十分です。ヒアドキュメント(<<EOF)で複数行を一気に渡す
引用符の仲間として覚えておくと便利なのが、ヒアドキュメント(here-document)です。複数行の入力を、まとめてコマンドの標準入力に渡す書き方で、シェルスクリプトのファイル生成や設定ファイル投入で頻出します。
$ cat <<EOF > /tmp/sample.txt 今日は$DATEです。 カレントディレクトリは$(pwd) EOF $ cat /tmp/sample.txt 今日は6月20日です。 カレントディレクトリは/home/pakira
<<EOF から、行頭に EOF が現れるまでの間が、まとめて cat の標準入力に渡されています。変数
$DATE やコマンド置換 $(pwd) は、ダブルクォートと同じく展開されます。変数を展開させたくない時は <<'EOF' とシングルクォートで囲む
ヒアドキュメントは、終端ワードをシングルクォートで囲むかどうかで挙動が変わります。# 終端をクォートしない:変数が展開される $ cat <<EOF 今日は$DATEです。 EOF 今日は6月20日です。 # 終端をシングルクォートで囲む:変数が展開されない $ cat <<'EOF' 今日は$DATEです。 EOF 今日は$DATEです。
<<'EOF' のようにシングルクォートで囲ってください。引用符を使い分ける実務シーン
シェルスクリプトでログメッセージを出す時
ログ出力では「変数を展開したい部分」と「リテラルで残したい部分」を分けるため、ダブルクォートが基本になります。LOG_FILE="/var/log/backup.log" NOW=$(date '+%Y-%m-%d %H:%M:%S') echo "[$NOW] バックアップ開始: $LOG_FILE" >> "$LOG_FILE"
"$LOG_FILE" のようにダブルクォートで括ります。これを忘れると、パスにスペースが入っている時にコマンドが失敗します。find や grep に正規表現を渡す時
正規表現はシェルに先に解釈されると意図しない結果になるため、必ずシングルクォートで渡します。$ find . -name '*.conf' -type f $ grep -E '^[Ee]rror.*([Tt]imeout|[Ff]ailed)' /var/log/messages
* や [Ee] をダブルクォートで囲むと、シェルのファイル名展開が先に効いてしまい、find/grepに正規表現として渡せないケースがあります。SSH越しにリモートでコマンドを実行する時
ssh先で変数展開を「ローカル側で行うか・リモート側で行うか」を、引用符の種類で切り替えます。# ローカルの $HOME を展開してからリモートに送る(ダブルクォート) $ ssh user@host "ls $HOME" # リモートの $HOME を展開する(シングルクォート) $ ssh user@host 'ls $HOME'
~ ではなくローカルの ~ を見にいく事故が起きます。トラブルシュート・よくある失敗
「変数が展開されない」と思ったらシングルクォートになっていた
シェルスクリプトで「変数$VAR を埋めたつもりが、リテラル文字列で出力されてしまう」最大の原因はこれです。画面上は
' と " がぱっと見区別しづらいので、エディタの文字色設定で区別できるようにしておくと事故が減ります。ダブルクォートの中に "(ダブルクォート)を書きたい
ダブルクォート内で" を表示したい時は、\" でエスケープします。$ echo "彼は\"Hello\"と言った" 彼は"Hello"と言った
cron で実行するとシングルクォートが壊れる
crontab の% はそのままだと改行扱いになり、引用符の中身が途中で切れます。crontabに date '+%Y%m%d' をそのまま書くと意図せず改行され、引用符が閉じずに unexpected EOF エラーになります。crontabでは
% を \% でエスケープしてください。# NG(%が改行扱いになって引用符が崩れる) 0 3 * * * /usr/local/bin/backup.sh 'log_$(date +%Y%m%d).txt' # OK(%をエスケープ) 0 3 * * * /usr/local/bin/backup.sh 'log_$(date +\%Y\%m\%d).txt'
シングルクォートの中にシングルクォートを書く
シングルクォート内ではエスケープが効かないため、いったん閉じて、エスケープした' を挟む方式が定石です。$ echo 'It'\''s OK' It's OK
'It' + \' + 's OK' の3パーツです。読みづらい時は、ダブルクォートで書き直したほうが安全です。本記事のまとめ
| 引用符 | 変数展開 | コマンド置換 | 主な用途 |
|---|---|---|---|
シングルクォート '...' |
されない | されない | 正規表現・パスワード・記号を含む文字列 |
ダブルクォート "..." |
される | される | 変数を含む通常のメッセージ・パス |
バッククォート `...` |
― | される | 古いスクリプトのコマンド置換(読む用) |
ドル丸カッコ $(...) |
― | される | 新規スクリプトのコマンド置換(推奨) |
ヒアドキュメント <<EOF |
される | される | 複数行入力・設定ファイル生成 |
ヒアドキュメント <<'EOF' |
されない | されない | テンプレートをそのまま出力する |
シングルクォート・ダブルクォート・バッククォートの使い分けがしっかり身につくと、シェルスクリプトの読みやすさと安全性が一段上がります。実機で
echo を打ちながら、それぞれの違いを手で確認してみてください。■関連記事
¥記号を入力するとバックスラッシュになる理由
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:メタキャラクタ|bashのシェル ワイルドカード(* ? [] {})の使い方
- 前のページへ:リダイレクトの使い方|>・>>・<・2>&1・/dev/nullの全パターン実践例
- この記事の属するカテゴリ:【Linux入門】初心者のための基礎知識・講座へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます