コマンドラインパラメータからどの文字をエスケープする必要がありますか?

コマンドラインパラメータからどの文字をエスケープする必要がありますか?

Bashでコマンドにコマンドライン引数を指定するときにどの文字をエスケープする必要がありますか?

|Bashのメタ文字であるスペース、タブ、、、、、、、、およびに制限されていますか?&;()<>

ベストアンサー1

場合によっては、次の文字はシェル自体に特別な意味を持ち、パラメータからエスケープする必要があるかもしれません。

特徴 Unicode 名前 使用法
` U+0060(アクセント) バックティック コマンドの置き換え
~ U+007E ティルデ チルダ拡張
! U+0021 感嘆符 歴史的拡張
# U+0023 数字記号 ハッシュ値 コメント
$ U+0024 ドル表示 パラメータ拡張
& U+0026 アンパサンド バックグラウンドコマンド
* U+002A スター ファイル名拡張子とワイルドカード
( U+0028 左括弧 サブシェル
) U+0029 右角かっこ サブシェル
U+0009 ラベル( ) 噴射(スペース)
{ U+007B 左中括弧 左支柱 サポート拡張
[ U+005B 左角かっこ ファイル名拡張子とワイルドカード
| U+007C垂直線 垂直ストリップ 管路
\ U+005C逆固相線 バックスラッシュ エスケープ文字
; U+003B セミコロン 別のコマンド
' U+0027アポストロフィ アポストロフィ 文字列参照
" U+0022 引用符 二重引用符 補間を含む文字列参照
U+000A 改行 新しいチーム 線を越えて
< U+003C 未満 入力リダイレクト
> U+003E より良い 出力リダイレクト
? U+003F 疑問符 ファイル名拡張子とワイルドカード
U+0020 スペース 噴射1 (スペース)

これらのキャラクターのいくつかは、私がリンクしたキャラクターよりも多くの仕事やより多くの場所で使用されています。


これが明示的にオプションであるいくつかの極端なケースがあります。


改行文字エスケープ引用が必要です- バックスラッシュは効果がありません。に記載されている他の文字IFS同様の処理が必要です。脱出し]たりする必要}はありませんが、する)演算子なのでエスケープする必要があります。

これらの文字のいくつかは、実際に逃げる必要があるときに他の文字よりも厳しい制限を適用します。たとえば、a#b大丈夫ですがa #bコメントですので>、どちらの場合もエスケープが必要です。それにもかかわらず、保守的に避けるのは悪いことではなく、微妙な違いを覚えているよりも簡単です。

コマンド名自体がシェルキーワード(if、、、)の場合、そのキーワードもエスケープまたは引用符で囲む必要がありますfordo唯一興味深いのは、in常にキーワードなので明確ではないということです。あなたいいえ(愚かなことに!)これらのキーワードの1つにちなんでコマンド名を指定した場合は、引数に使用されているキーワードに対してのみこれを実行できます。シェル演算子((など&)は、使用されるたびに常に引用符が必要です。


1ステファンは異なる点を指摘しています。シングルバイト地域の空白文字脱出も必要です。最も一般的で合理的なロケール(少なくともCまたはUTF-8ベースのロケール)では、上記の空白文字にすぎません。 U + 00A0改行なしのスペースは、Solaris、BSD、およびOS Xを含む一部のISO-8859-1ロケールでスペースとして扱われます(私の考えでは間違っているようです)。未知のロケールを扱う場合は、文字を含むすべてが含まれる可能性があるため、幸運です。

空白と見なされる単一バイトがある可能性があると考えることができます。以内に空白ではなくマルチバイト文字なので、文字全体を引用符で囲む以外にエスケープする方法はありません。これは理論的な問題ではありません。上記のISO-8859-1ロケールには、空白として扱われるバイトがA0含まれている可能性があります。以内にUTF-8でエンコードされた「à」()などのマルチバイト文字ですC3 A0。これらの文字を安全に処理するには、その文字を引用する必要があります"à"。この動作は、スクリプトを作成する環境のロケール構成ではなく、スクリプトが実行される環境のロケール構成によって異なります。

私はこの行動がさまざまな方法で壊れる可能性があると思いますが、私たちは与えられたカードで遊ぶ必要があります。自己同期しないマルチバイト文字セットを使用する場合、最も安全な方法はすべての項目を引用することです。 UTF-8またはCを使用すると(現在は)安全です。

おすすめ記事