シェルスクリプトで変数を参照する

シェルスクリプトで変数を参照する

シェル スクリプトで、 などの変数を定義した場合、それを として参照する場合とFOO=25として参照する場合に違いはありますか?$FOO$${FOO}$

答え1

ほとんどの場合、$varと は${var}同じです。($最後に を使用してはいけないことに注意してください。)

中括弧が必要になる例としては、連続した文字列に変数を配置する必要がある場合が挙げられます。

例:

var=hel
echo ${var}lo

を出力しますhello

答え2

あなたの主な質問に答えると、${foo}あなた「パラメータ拡張」正確に言うと、それ$自体がパラメータ展開を開始し、{ }実際にはオプションであり、POSIX仕様ですが、変数名の終わりを示すのに便利です。

$ foo="bar"
$ echo $fooBaz   ## fails, no variable named $fooBaz exists

$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz

基本的に、$fooそして${foo}は同じです。上記のような場合や、文字列操作、それらは完全に同等です。

しかし、どちらも実際には使用すべきではありません。経験則としては、ごくわずかな例外を除いて、いつも"$foo"orを使用してください。 or は"${foo}"絶対に使用しないでください。split+glob 演算子 (後述) の呼び出しを避けるために、常に変数を引用符で囲む必要があります。 は絶対に使用しないでください。 は無関係です。$foo${foo}$foo$$

$ foo="bar"
$ echo "$foo$"
bar$

したがって、引用符で囲まれていない変数でも問題ない場合もあります。

$ echo $foo
bar

これらは通常そうではなく、本当に避けるべきです:

$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty

$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty

ここでも括弧は役に立たないことに注意してください。

$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi  ## fails
empty

$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty

$fooまたはを使用すると${foo}、シェルはスプリット変数に保存された空白の値(これは変数IFSを別の値に設定することで変更できます)をリストに格納し、リストの各要素をグロブパターンは、一致するファイルやディレクトリに展開されます。これは分割+グロブ演算子。例として、2 つのファイルがあるディレクトリを考えてみましょう。

$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct  9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct  9 18:16 file2

さて、変数を次のように設定しましょうfoo *:

$ foo="foo *"

その名前のファイルが存在するかどうかを確認しようとするとどうなりますか?

$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists

変数はfooとに分割され*、 は*任意の文字列に一致するワイルドカードであるため、シェルはfoo *exxists というファイルがあることを伝えます。ただし、正しく引用符で囲めば、このようなことは起こりません。

$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file

これは要点を説明するための些細な例です。thoughrmの代わりにを使用した場合を想像してみてくださいecho

最初のルールは次のとおりです。変数は常に引用符で囲んでください。または のどちらかを使用できます"$foo"が、"${foo}"どちらの場合も引用符で囲みます。変数を安全に使用する方法の詳細については、次の投稿を参照してください。

関連情報