回答:
引用符は、シェルが特殊文字とみなし、構文上の意味を持つ文字に影響を与えます。この例では、このapple
ような文字が含まれていないため、違いはありません。
しかし、別の例を考えてみますgrep apple tree file
単語を検索しますapple
ファイルにtree
してfile
、一方grep "apple tree" file
の単語を検索するapple tree
ファイルにfile
。引用符は、bashに、単語スペースが"apple tree"
新しいパラメーターを開始するのではなく、現在のパラメーターの一部となることを示します。grep apple\ tree file
なぜなら\
、次の文字の特別な意味を無視して文字通りに扱うようにbashに指示するからです。
"
)と単一引用符('
)の違いです。単一引用符は、などの特定の文字の解釈を防ぎ$
ますが、二重引用符は解釈を許可します。例えば、grep '${USER}'
テキストを探します${USER}
一方、grep "${USER}"
変数があること、テキストを探しますUSER
含まれている(例えばjohnstacen
)。
コマンドラインで使用した場合、二重引用符で評価でき、単一引用符で評価できず、引用符でワイルドカードを展開できません。考案された例として:
[user@work test]$ ls .
A.txt B.txt C.txt D.cpp
# The following is the same as writing echo 'A.txt B.txt C.txt D.cpp'
[user@work test]$ echo *
A.txt B.txt C.txt D.cpp
[user@work test]$ echo "*"
*
[user@work test]$ echo '*'
*
# The following is the same as writing echo 'A.txt B.txt C.txt'
[user@work test]$ echo *.txt
A.txt B.txt C.txt
[user@work test]$ echo "*.txt"
*.txt
[user@work test]$ echo '*.txt'
*.txt
[user@work test]$ myname=is Fred; echo $myname
bash: Fred: command not found
[user@work test]$ myname=is\ Fred; echo $myname
is Fred
[user@work test]$ myname="is Fred"; echo $myname
is Fred
[user@work test]$ myname='is Fred'; echo $myname
is Fred
引用の仕組みを理解することは、Bashを理解する上で極めて重要です。例えば:
# for will operate on each file name separately (like an array), looping 3 times.
[user@work test]$ for f in $(echo *txt); do echo "$f"; done;
A.txt
B.txt
C.txt
# for will see only the string, 'A.txt B.txt C.txt' and loop just once.
[user@work test]$ for f in "$(echo *txt)"; do echo "$f"; done;
A.txt B.txt C.txt
# this just returns the string - it can't be evaluated in single quotes.
[user@work test]$ for f in '$(echo *txt)'; do echo "$f"; done;
$(echo *txt)
単一引用符を使用して、変数を介してコマンドを渡すことができます。単一引用符は評価を妨げます。二重引用符が評価されます。
# This returns three distinct elements, like an array.
[user@work test]$ echo='echo *.txt'; echo $($echo)
A.txt B.txt C.txt
# This returns what looks like three elements, but it is actually a single string.
[user@work test]$ echo='echo *.txt'; echo "$($echo)"
A.txt B.txt C.txt
# This cannot be evaluated, so it returns whatever is between quotes, literally.
[user@work test]$ echo='echo *.txt'; echo '$($echo)'
$($echo)
ダブルクォート内でシングルクォートを使用でき、ダブルクォート内でダブルクォートを使用できますが、シングルクォート内のダブルクォートは(エスケープせずに)行われるべきではなく、文字通りに解釈されます。単一引用符内の単一引用符は(エスケープせずに)実行しないでください。
Bashを効果的に使用するには、引用符を完全に理解する必要があります。非常に重要です!
一般的なルールとして、Bashで要素(配列など)に何かを展開する場合は引用符を使用せず、変更しないリテラル文字列には単一引用符を使用し、変数には二重引用符を自由に使用しますあらゆるタイプの文字列を返す可能性があります。これは、スペースと特殊文字が確実に保持されるようにするためです。
grep a*b equations.txt
、それは検索されますa*b
で始まる現在のディレクトリにファイルがある場合を除き、aとbで終わる、(理由は(BA)のshは、コマンドラインでファイル名を拡大します)その場合に呼び出されますグレップさまざまなパラメーターを入力すると、結果が異なります。これは通常、findの問題find . -name *.txt
です。現在のディレクトリにtxtファイルがある場合、次のようなコマンドは予期しない動作を引き起こすためです。この場合、引用符を使用することをお勧めします。