回答:
一重引用符は何も補間しませんが、二重引用符は補間します。例:変数、バックティック、特定の\
エスケープなど。
例:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
Bashのマニュアルにはこう書いてある:
文字を一重引用符で囲む(
'
)、引用符内の各文字のリテラル値が保持されます。バックスラッシュが前に付いていても、一重引用符は一重引用符の間に出現しない場合があります。(二重引用符で文字を囲む
"
)を除いて、全ての文字のリテラル値を保持し$
、`
、\
、履歴展開が有効になっている場合、および!
。文字$
と`
は、二重引用符内で特別な意味を保持します(シェル展開を参照)。バックスラッシュは、次の文字のいずれかが続く場合にのみその特別な意味を保持し:$
、`
、"
、\
、または改行。二重引用符内では、これらの文字のいずれかが後に続くバックスラッシュが削除されます。特別な意味のない文字の前のバックスラッシュは変更されません。二重引用符は、バックスラッシュを前に付けることにより、二重引用符で囲むことができます。有効に!
すると、二重引用符で囲まれた箇所がバックスラッシュを使用してエスケープされない限り、履歴の展開が実行されます。の前のバックスラッシュ!
は削除されません。特別なパラメーターは、二重引用符で囲まれたときに特別な意味
*
を@
持ちます(シェルパラメーターの展開を参照)。
PS1
ます。echo $PS1
私が何を意味するか見てみてください。ただしPS1
、表示される前に評価されます(PROMPTING
bashマンページのセクションを参照)。これをテストするには、を試してくださいPS1='$X'
。プロンプトは表示されません。次に実行するX=foo
と、突然プロンプトが「foo」になります(設定PS1
されたときに表示されずに評価された場合、プロンプトは表示されません)。
受け入れ答えは素晴らしいです。トピックをすばやく理解するのに役立つ表を作成しています。説明には、単純な変数a
とインデックス付き配列が含まれますarr
。
設定したら
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
次にecho
2列目の式では、3列目に示す結果/動作が得られます。4列目は動作を説明しています。
# | Expression | Result | Comments
---+-------------+-------------+--------------------------------------------------------------------
1 | "$a" | apple | variables are expanded inside ""
2 | '$a' | $a | variables are not expanded inside ''
3 | "'$a'" | 'apple' | '' has no special meaning inside ""
4 | '"$a"' | "$a" | "" is treated literally inside ''
5 | '\'' | **invalid** | can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
6 | "red$arocks"| red | $arocks does not expand $a; use ${a}rocks to preserve $a
7 | "redapple$" | redapple$ | $ followed by no variable name evaluates to $
8 | '\"' | \" | \ has no special meaning inside ''
9 | "\'" | \' | \' is interpreted inside "" but has no significance for '
10 | "\"" | " | \" is interpreted inside ""
11 | "*" | * | glob does not work inside "" or ''
12 | "\t\n" | \t\n | \t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13 | "`echo hi`" | hi | `` and $() are evaluated inside ""
14 | '`echo hi`' | `echo hi` | `` and $() are not evaluated inside ''
15 | '${arr[0]}' | ${arr[0]} | array access not possible inside ''
16 | "${arr[0]}" | apple | array access works inside ""
17 | $'$a\'' | $a' | single quotes can be escaped inside ANSI-C quoting
18 | "$'\t'" | $'\t' | ANSI-C quoting is not interpreted inside ""
19 | '!cmd' | !cmd | history expansion character '!' is ignored inside ''
20 | "!cmd" | cmd args | expands to the most recent command matching "cmd"
21 | $'!cmd' | !cmd | history expansion character '!' is ignored inside ANSI-C quotes
---+-------------+-------------+--------------------------------------------------------------------
以下も参照してください。
The special parameters * and @ have special meaning when in double quotes
ので、どうして"*"
結果は*
どうなるのですか?
"$@"
および"$*"
パラメータ拡張です。"@"
あり"*"
ません。
echo "\'"
、私を返します\'
。
他の人は非常によく説明し、単純な例を挙げたいだけです。
シェルが特殊文字を解釈しないようにするために、テキストを単一引用符で囲むことができます。単一引用符で囲まれている場合、ドル記号、スペース、アンパサンド、アスタリスク、およびその他の特殊文字はすべて無視されます。
$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
これは次のようになります。
All sorts of things are ignored in single quotes, like $ & * ; |.
一重引用符で囲むことができない唯一のものは一重引用符です。
二重引用符は、シェルがドル記号、逆引用符、バックスラッシュを解釈できることを除いて、単一引用符と同様に機能します。バックスラッシュが単一の特殊文字の解釈を妨げることはすでに知られています。変数の代わりにドル記号をテキストとして使用する必要がある場合は、二重引用符で囲むと便利です。また、二重引用符をエスケープして、引用符付き文字列の終わりと解釈されないようにすることもできます。
$ echo "Here's how we can use single ' and double \" quotes within double quotes"
これは次のようになります。
Here's how we can use single ' and double " quotes within double quotes
また、引用符で囲まれた文字列の先頭として解釈されるアポストロフィは、二重引用符内では無視されることにも注意してください。ただし、変数は解釈され、二重引用符で囲まれた値に置き換えられます。
$ echo "The current Oracle SID is $ORACLE_SID"
これは次のようになります。
The current Oracle SID is test
逆引用符は、一重引用符や二重引用符とはまったく異なります。特殊文字の解釈を防ぐために使用されるのではなく、逆引用符は実際にそれらが囲むコマンドの実行を強制します。囲まれたコマンドが実行された後、その出力は元の行の逆引用符の代わりに置き換えられます。これは例でより明確になります。
$ today=`date '+%A, %B %d, %Y'`
$ echo $today
これは次のようになります。
Monday, September 28, 2015
' '
との使用法には明確な違いがあり" "
ます。
いつ ' '
が何かの周りで使用される、「変換または翻訳」は行われません。そのまま印刷されます。
と " "
、それが取り巻くものは何でも、その値に「変換または変換」されます。
翻訳/変換とは、次のことを意味します。単一引用符内のすべてのものは、それらの値に「変換」されません。彼らは引用符の中にあるので、それらは取られます。例:a=23
、標準出力にecho '$a'
生成$a
します。一方、標準出力でecho "$a"
生成さ23
れます。
これは引用符を扱う際の事実上の答えなので bash
であるため、シェルで算術演算子を処理する場合、上記の答えで見逃していた点をもう1つ追加します。
bash
シェルは2つの方法が演算を行うサポート、によって定義さ組み込みlet
コマンドと$((..))
オペレータ。前者は算術式を評価しますが、後者はより複雑なステートメントです。
で使用される算術式は、let
他のシェルコマンドと同様に、単語分割、パス名展開されることを理解することが重要です。したがって、適切な引用とエスケープを行う必要があります。
使用するときにこの例を参照してください let
let 'foo = 2 + 1'
echo $foo
3
ここでは一重引用符を使用しても問題ありません。ここでは変数を展開する必要がないため、
bar=1
let 'foo = $bar + 1'
$bar
下の単一引用符は拡張されず、次のように二重引用符で囲む必要があるため、無残に失敗します。
let 'foo = '"$bar"' + 1'
これは理由の1つである$((..))
必要がありますlet
。は常にの使用よりも検討する必要があります。その内部では、コンテンツは単語分割の対象ではありません。前の例を使用let
すると、簡単に次のように書くことができます
(( bar=1, foo = bar + 1 ))
$((..))
単一引用符なしで使用することを忘れないでくださいは$((..))
二重引用符で使用できますが、二重引用符が必要なコンテンツを含めることができないため、目的はありません。単一引用符で囲まれていないことを確認してください。
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
$((..))
単一引用符で囲まれた文字列内で演算子を使用するいくつかの特別な場合があるかもしれませんが、演算子を引用符で囲まないままにするか、二重引用符で囲むように引用符を補間する必要があります。例を考えてみましょう。curl
ステートメント内で演算子を使用して、リクエストが行われるたびにカウンターを渡す場合は、次のようにします。
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
内部でネストされた二重引用符の使用に注意してください。二重引用符を使用しないと、リテラル文字列$((reqcnt++))
がrequestCounter
フィールドに渡されます。
$((...))
に適しています。それは「少し」偏執的である可能性がありIFS=0
、たとえばそうすることはほとんどありませんが、それは確かに不可能ではありません:)
$[[...]]
構文もありますが、おそらくあなたはそれを忘れていたでしょう。