いつ引用符を使用する必要がありますか?

いつ引用符を使用する必要がありますか?

私はちょうどBashを学び始めたので、次の質問があまりにも基本的に見えるかもしれないことをお詫び申し上げます。

シェルスクリプトで引用符の使用を理解するのに問題があります。

書きたいなら

a="file"
b="`grep " a" "$a"`"
echo $b
  1. "$a" と "a" を引用符 "`grep" a" "$a"`" で読む必要がありますか?

    それとも左から右に読みますか?

    変数を二重引用符で囲む方法を学んだからです。

    私をさらに混乱させることは、先生がシステムが変数名とそれに続くテキストを誤解するのを防ぐために、変数名の周りに別の二重引用符を追加する必要があると言ったことです。

  2. 入れ子になった引用符は何をしますか?いつ引用符を使用する必要がありますか?

答え1

一重引用符は入れ子にすることはできませんが、バックティックは二重引用符で特別です。

$()バックティックの代わりにこれを使用する方が読みやすく簡潔です。彼らはすべて意味コマンドの置き換えつまり、含まれているコマンドの出力に展開されます。

b="$(grep " a" "$a")"

ただし、割り当てに外部二重引用符を使用する必要はないため、以下は同じです。

b=$(grep " a" "$a")

ご質問が変更されましたので、詳細を追加してみましょう。単語の区切りを防ぐには、どこでも二重引用符を使用する必要があります。変数名の問題は、以下で最もよく説明されています。

echo "$var1_$var2"    # two variables, $var1_ and $var2
echo "$var1"_"$var2"  # two variables, $var1 and $var2, separated by an underscore
# also possible:
echo "${var1}_$var2"

答え2

バックティックを使用して古代の形式のコマンド置換を使用しているので、答えは「状況によって異なります」です。一部のシェル(Bashなど)はバックティックを使用して新しい引用符のコンテキストを開始するため、内部二重引用符ペアはバックティックと外部二重引用符内にネストされ、次の4つの引用符で終わります。

b="`grep " a" "$a"`"
#        c--c d--d
#  b--------------b
# a----------------a

しかし...他のいくつかのシェル(ksh)は、中間のバックティックに関係なく、2番目の二重引用符が二重引用符で囲まれた文字列を終了するように解析します。結果は次のとおりです。

b="`grep " a" "$a"`"
# a------a  b-b  c-c

これにより、目的の効果が得られません。( を実行しgrep ''、出力を に割り当ててから、与えられた引数ba空のコマンドで置き換えて実行します。)

望むより:kshの逆引用符内の引用符

当然、POSIX はこのような状況を定義しません。


つまり、コマンド置換を使用する形式に変更したい場合は、$(...)これを防ぐことができます。この場合、拡張は常に新しい引用符のコンテキストを開始するため、二重引用符内にネストされ、二重引用符内にネストされます$(...)

b="$(grep " a" "$a")"
#         c--c d--d
#   b--------------b
# a-----------------a

望むより:

友人はバックティックを使用することはできません。


私をさらに混乱させることは、先生がシステムが変数名とそれに続くテキストを誤解するのを防ぐために、変数名の周りに別の二重引用符を追加する必要があると言ったことです。

引用符を使用するか、変数名を中かっこで囲むことができます。したがって、3つのバリエーションすべてで、次は$foo固定文字列に展開され、追加されますbar

$ foo=xxx
$ echo "$foo""bar" "$foo"bar "${foo}bar" 
xxxbar xxxbar xxxbar

最後のものはおそらく最も読みやすいでしょう。

入れ子になった引用符は何をしますか?いつ引用符を使用する必要がありますか?

前述のように、コマンド置換のようなものがない場合、引用符は互いに入れ子になりません。 1つもなければ、同様の引用符は引用符で終わりますが、他の引用符は通常の文字のように機能し、何も引用しません。

たとえば、以下は、中間に引用符が付けられていない部分を持つ2つの引用符付き文字列です。

  "foo "abc def" bar"
# <---->       <---->
#          ^ unquoted space.

これは、正確に単一の一重引用符文字を含む引用符付き文字列です。

$ echo "foo 'abc def' bar"
foo 'abc def' bar

echo一重引用符は、文字やスペースと同様に、コマンドライン引数の一部として渡されます。彼らは何も引用しません。

いつのかについては、以下をご覧ください。いつ二重引用符が必要ですか?

関連情報