回答:
VAR=$VAR1
はの簡易版ですVAR=${VAR1}
。2番目にできること、1番目にはできないことがあります。たとえば、配列インデックスを参照する(移植性がない)、またはサブストリングを削除する(POSIX移植可能)。POSIX仕様のBash Guide for Beginners and Parameter Expansionの変数の詳細セクションを参照してください。
rm -- "$VAR1"
またはのように変数を引用符で囲むことをrm -- "${VAR}"
お勧めします。これにより、変数の内容がアトミック単位になります。変数値に空白(まあ、$IFS
特殊変数の文字、デフォルトでは空白)またはグロビング文字が含まれていて、引用符で囲まない場合、各単語はファイル名生成(グロビング)のために考慮されます。やっています。
$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'
$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename
移植性について:POSIX.1-2008セクション2.6.2によると、中括弧はオプションです。
var1=$var
拡張によりエラーが発生するシェルの実際の例はありますか?
export VAR=$VAR1
です。中括弧については、オプションです(引用したセクションの4番目の段落を確認してください。これは、すべてのPOSIX以前およびPOSIXシェルの場合です)。
${VAR}
と$VAR
まったく同じです。単純な変数展開の場合、使用する唯一の理由${VAR}
は、構文解析で変数名にあまりにも多くの文字を取り込む場合です${VAR1}_$VAR2
(中括弧なしはに相当します${VAR1_}$VAR2
)。ほとんどの飾られた拡張(${VAR:=default}
、${VAR#prefix}
、...)は、中括弧が必要です。
変数の割り当てでは、フィールドの分割(値の空白での分割)とパス名の展開(つまりグロビング)がオフになるため、すべてのPOSIXシェルおよび聞いたすべてのPOSIX以前のsh VAR=$VAR1
とまったく同じVAR="$VAR1"
です。 。(POSIX ref:単純なコマンド)。同じ理由で、VAR=*
確実VAR
にリテラル文字列に設定します*
; が最初に別の単語であるため、もちろんVAR=a b
設定VAR
されます。一般的に言えば、シェルの構文は、例えば、単一の単語を予測する場合、二重引用符は不要ですに(ではないパターンで)、それでもそこには注意する必要があります。たとえばPOSIXがあることを指定しますa
b
case … in
リダイレクトターゲット(>$filename
)はスクリプト内で引用符を必要としませんが、bashを含むいくつかのシェルはスクリプト内でも二重引用符を必要とします。二重引用符が必要な場合を参照してください。より徹底的な分析のため。
他の場合、特に多くのシェルで(export VAR="${VAR1}"
同等に記述できるexport "VAR=${VAR1}"
)に二重引用符が必要です(POSIXはこの場合を開いたままにします)。このケースと単純な割り当ての類似性、および二重引用符を必要としないケースのリストの散在性により、分割とグロブを行わない限り、二重引用符を使用することをお勧めします。
IFS
、習慣にしたいので値に文字が含まれないことがわかっていても、変数展開を常に引用します。1つの例外は、変数の割り当て時に値を引用しないことです(値にスペースが含まれる場合など、必要な場合を除きます)。これにより、などのコマンド置換がある場合、エディター構文の強調表示がより便利になりますFOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
。すべてを「文字列」の色で着色するのではなく、ネストされたコードの構文を強調表示します。これが、逆戻りを避ける理由でもあります。
>$file
POSIXスクリプトでOKですが、それは非対話(POSIX準拠のに強制されない限り場合でも、bashではありません$POSIXLY_CORRECT
か--posix
...)。
VAR=$VAR1
、に驚かされることがlocal VAR=$VAR1
あります。いくつかの点で、少なくともいくつかのシェルでは、異なる方法で作業したことを覚えています。しかし、ATM、私は発散を再現することはできません。
local VAR=$VAR1
はのようなものexport VAR=$VAR1
で、シェルに依存します。
二重引用符は変数の展開に使用され、単一引用符は強い引用、つまりsans拡張に使用されることを考慮してください。
this='foo'
that='bar'
these="$this"
those='$that'
for item in "$this" "$that" "$these" "$those"; do echo "$item"; done
foo
bar
foo
$that
いくつかの理由で可能な限り引用を使用する必要があることに言及する価値があるかもしれませんが、その中で最も優れているのは、ベストプラクティスと読みやすさです。また、Bashは時々、一見非論理的または不合理/予期しない方法で風変わりであり、引用が暗黙的な期待を明示的に変更するため、エラーサーフェス(またはその潜在性)が減少します。
そして、引用しないことは完全に合法であり、ほとんどの場合に機能しますが、その機能は利便性のために提供されており、おそらく移植性が低くなります。意図と期待を反映することが保証されている完全に正式な慣行は引用することです。
ここで、構造"${somevar}"
が置換操作に使用されることも考慮してください。置換や配列など、いくつかのユースケース。
thisfile='foobar.txt.bak'
foo="${thisfile%.*}" # removes shortest part of value in $thisfile matching after '%' from righthand side
bar="${thisfile%%.*}" # removes longest matching
for item in "$foo" "$bar"; do echo "$item"; done
foobar.txt
foobar
foobar='Simplest, least effective, least powerful'
# ${var/find/replace_with}
foo="${foobar/least/most}" #single occurrence
bar="${foobar//least/most}" #global occurrence (all)
for item in "$foobar" "$foo" "$bar"; do echo "$item"; done
Simplest, least effective, least powerful
Simplest, most effective, least powerful
Simplest, most effective, most powerful
mkdir temp
# create files foo.txt, bar.txt, foobar.txt in temp folder
touch temp/{foo,bar,foobar}.txt
# alpha is array of output from ls
alpha=($(ls temp/*))
echo "$alpha" # temp/foo.txt
echo "${alpha}" # temp/foo.txt
echo "${alpha[@]}" # temp/bar.txt temp/foobar.txt temp/foo.txt
echo "${#alpha}" # 12 # length of first element (implicit index [0])
echo "${#alpha[@]}" # 3 # number of elements
echo "${alpha[1]}" # temp/foobar.txt # second element
echo "${#alpha[1])" # 15 # length of second element
for item in "${alpha[@]}"; do echo "$item"; done
temp/bar.txt
temp/foobar.txt
temp/foo.txt
これはすべて、"${var}"
置換コンストラクトの表面をかろうじて引っ掻いているだけ です。Bashシェルスクリプトの決定的なリファレンスは、libreオンラインリファレンス、TLDP The Linux Documentation Projectです。https://www.tldp.org/LDP/abs/html/parameter-substitution.html