「…」、「…」、「$」…、および「$」…引用符の違いは何ですか?


49

時々私はスクリプトがいくつかのテキストを引用し、これらのさまざまな方法のすべてを使用して参照してください"..."'...'$'...'、と$"..."。なぜ非常に多くの種類の引用が使用されているのですか?

それらは異なる振る舞いをしたり、それらの中で私ができることに影響を与えますか?


1
クロスサイトの重複の可能性。この回答は、すべての異なるタイプの引用符のセマンティクスの要約(またはリンク)を提供します。
chepner

回答:


66

これらはすべて異なるものを意味し、その中に異なるもの(または異なる意味を持つ同じもの)を書くことができます。異なる種類の引用符は\something、その中の異なるエスケープシーケンスを解釈する()か、変数の補間($something)およびその他の種類の展開を許可するかしないかを指定します。

要するに:

  • '...' 完全にリテラルです。
  • "..." 変数と埋め込み引用符文字の両方を許可します。
  • $'...'のような文字エスケープを実行しますが\n、変数を展開しません。
  • $"..." Bashとkshでの人間の言語の翻訳用です。

「単一引用符」

単一引用符の間に書くものはすべて文字通り処理され、まったく処理されません。バックスラッシュとドル記号には特別な意味はありません。つまり、文字(他の一重引用符を含む!)をバックスラッシュでエスケープしたり、変数を補間したり、その他のシェル機能を使用したりすることはできません。

これらの例はすべて、引用符の間に文字通り書かれたものになります。

'hello world'                     => hello world
'/pkg/bin:$PATH'                  => /pkg/bin:$PATH
'hello\nworld'                    => hello\nworld
'`echo abc`'                      => `echo abc`
'I\'dn\'t've'                     => I\dn'tve

最後のものは複雑です- 引用符で囲まれていないテキストと一緒に実行される2つの単一引用符で囲まれた文字列があります。最初のものにはが含まれますI\。引用符で囲まdn\'tれていないテキストには、シェルレベルでエスケープれた単一引用符が含まれているため、引用符で囲まれた文字列を開始せず、リテラル文字として含まれています(so、dn't)。最後の引用文字列はだけveです。これらはすべて、シェルの通常の動作方法で1つの単語にまとめられます。

リテラルテキストと変数を組み合わせるためのやや一般的なイディオムは、次のように一緒に実行することです。

'let x="'$PATH\"

になります

let x="/usr/bin:/bin"

単一の単語として($PATH場合によっては二重引用符の方が適切です - 変数値のスペースまたはグロビング文字は別の方法で処理されます -しかし、読みやすい実行例のために私はしていません)。


「二重引用符」

二重引用符内では、2種類の展開が処理されます。バックスラッシュを使用して文字をエスケープし、展開またはエスケープが処理されないようにすることができます。

二重引用符内で発生する展開の2つのカテゴリがあります。

引用符の中では、円記号は$orの前に置くことでそれらの展開を禁止でき`ます。二重引用符をエスケープすることもできるため、文字列または別のバックスラッシュに\"含めることができ"ます。他のバックスラッシュは文字通り保存されます-他の文字を生成するためのエスケープはなく、削除されません。

これらの例の中には、以前とは異なる動作をするものとそうでないものがあります。

"hello world"                     => hello world
"/pkg/bin:$PATH"                  => /pkg/bin:/bin:/usr/bin
"hello\nworld"                    => hello\nworld
"hello\\nworld"                   => hello\nworld
"`echo abc`"                      => abc
"I\'dn\'t've"                     => I\'dn\'t've
"I'dn't've"                       => I'dn't've
"I\"dn\"t've"                     => I"dn"t've

$ 'ANSI-C引用'

このようなクォートにより、Cスタイルのバックスラッシュエスケープを処理できますが、埋め込み変数または置換はできませんこれは、文字エスケープをサポートする唯一の種類の引用です

これはkshの拡張機能であり、Bash、zsh、およびその他のシェルでもサポートされるようになりました。これはまだ POSIX標準の一部ではないため、最大限に移植可能なスクリプトでは使用できませんが、Bashまたはkshスクリプトは自由に使用できます。

これらのエスケープのすべてのCの意味で使用することができます:\a\b\f\n\r\t\v、およびリテラルエスケープ\\\'\"、と\?。また、拡張機能\e(エスケープ文字)とBashおよびksh \cxCtrl-xで入力れるもの、たとえば\cMキャリッジリターン)もサポートします。シェルには、独自のさまざまなマイナー拡張機能があります。

また、4種類の一般的な文字エスケープが可能です。

  • \nnn、8進数値nnnの単一バイト
  • \xHH、16進値HHの単一バイト
  • \uHHHH、16進インデックスがHHHHであるUnicodeコードポイント
  • \UHHHHHHHH、16進インデックスがHHHHHHHHであるUnicodeコードポイント

これらの数字はすべて、最初の数字の後のオプションです。

$そして、`意味がありませんし、あなたが変数そこを含めることはできませんので、文字通りに保存されています。

$'hello world'                    => hello world
$'/pkg/bin:$PATH'                 => /pkg/bin:$PATH
$'hello\nworld'                   => hello
                                     world
$'`echo abc`'                     => `echo abc`
$'I\'dn\'t\'ve'                   => I'dn't've
$'\U1f574\u263A'                  => 🕴☺

これらのほとんどは、あなたが使用してシミュレートすることができエスケープコマンドを POSIXにのみ必要ですが、、、、、、、、、およびそこに仕事に。必要に応じて、コマンド置換を使用して二重引用符を埋め込むことができます。printf\\\a\b\f\n\r\t\v\nnnprintf"Path:$(printf '\t')$PATH"


$「ロケール翻訳」

これは、自然言語のテキスト文字列をローカライズするためのkshおよびBash固有の拡張機能であり、メッセージカタログ内の引用符内の部分を検索します。最初にすべての二重引用符展開を実行します。文字列が翻訳データベースで見つからない場合、それは独自の翻訳として使用されます。組み込みの前提は、文字列が英語であるということです。

おそらくこれを使いたくはないでしょうが、もし見たなら、通常は通常の二重引用符として扱うことができます。


注意すべき点の1つは、埋め込みパラメーターの展開と埋め込み文字のエスケープの両方を許可するクォートはないということです。あなたがそれを望むほとんどの場合、以下を使用する方が安全printfです:

printf 'New path: \e[1m%s\e[0m' "/pkg/bin:$PATH:"

これにより、文字エスケープの対象となる部分とデータ値である部分が明確に区別されます。

もう1つは、二重引用符内で配列拡張が使用されない限り 、これらのスタイルの引用のすべてがシェルで単一の「単語」を作成することです。どちらの単一引用符形式も常に1つの単語であり、それ以上展開されることはありません。$@${x[@]}


$"..."2.0でbashに追加されたksh93からでもあります。
ステファンシャゼラス

何もありません\cXではzsh。それはだ\CX\C-Xが(\cすでに特別な意味を持つecho
ステファンChazelas

'let x="'$PATH\"引用符で囲まzsh$PATHていない以外のシェルのリストコンテキストでは間違っています(したがって、ここでは不要なsplit + globの影響を受けます)。
ステファンシャゼラス

あなたはあなたが話していることを明確にしたいことがありコーン状のシェル、引用処理が... cshの、RC、魚が異なっている
ステファンChazelas

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.