Bashとコマンドライン引数のシェルエスケープ

Bashおよびシェル環境で文字列を適切にエスケープする方法を学びます。シングルクォート、ダブルクォート、バックスラッシュエスケープ、特殊文字、コマンド置換の防止、安全な引数渡しを解説します。

Advanced Patterns

詳細な説明

シェルエスケープ

シェル(Bash)は多くの文字を特別に解釈します — スペースは引数を分割し、$ は変数展開をトリガーし、バッククォートはコマンドを実行し、globパターンはファイル名を展開します。ファイル名、ユーザー入力、特殊文字を含むデータを処理するスクリプトには適切なエスケープが不可欠です。

3つのエスケープメカニズム

Bashは特殊解釈を防ぐ3つの方法を提供します:

1. シングルクォート — 最強のエスケープ

シングルクォート間のすべてがリテラルです。バックスラッシュを含め、特殊な文字はありません。唯一含められない文字はシングルクォート自体です。

2. ダブルクォート — 選択的エスケープ

ダブルクォートはワード分割とglobを防ぎますが、変数展開とコマンド置換は許可します。ダブルクォート内で特殊な文字は $\`\"!`(対話シェル)のみです。

3. バックスラッシュ — 単一文字エスケープ

任意の文字の前にバックスラッシュを置くとリテラルになります。

エスケープが必要な文字

クォートなしで特殊な意味を持つ文字:

スペース、タブ、改行   → 引数セパレータ
*  ?  [  ]            → glob / ファイル名展開
$                     → 変数展開
\`                     → コマンド置換
"  '                  → クォーティング
\\                     → エスケープ文字
|  &  ;               → コマンド演算子
(  )                  → サブシェル
<  >                  → リダイレクション
#                     → コメント
~                     → ホームディレクトリ
!                     → ヒストリ展開(対話モード)
{  }                  → ブレース展開

シングルクォート文字列内へのシングルクォートの埋め込み

シングルクォート内ではシングルクォートをエスケープできないため、連結を使用します:'It'\\''s a test'

安全な変数の使用

ワード分割とglobを防ぐため、変数展開は常にダブルクォートで囲みましょう。

printfによるプログラム的エスケープ

printf %q を使用して、任意の文字列のシェルエスケープ版を生成できます。

ユースケース

シェルエスケープは、デプロイスクリプトの記述、CI/CDパイプラインの構築、スペースや特殊文字を含むファイル名の処理、子プロセスへの引数渡し、リモートSSHコマンドの構築、環境変数を含むDocker runコマンドの構築、cronジョブエントリの記述、アプリケーションコードからシェルコマンドを実行するあらゆる自動化に必要です。

試してみる — String Escape/Unescape

フルツールを開く