When do we need curly braces around shell variables?
在shell脚本中,扩展变量时何时使用
例如,我看到了以下内容:
| 1 2 3 4 | var=10        # Declare variable echo"${var}" # One use of the variable echo"$var" # Another use of the variable | 
是有显著的区别,还是只是风格?一个比另一个更受欢迎吗?
在这个特定的例子中,它没有任何区别。但是,如果要扩展字符串中的变量
| 1 | "${foo}bar" | 
由于
在下列情况下,也无条件地需要大括号:
- 扩展数组元素,如${array[42]} 。
- 使用参数扩展操作,如${filename%.*} (删除扩展)
- 将位置参数扩展到9以外:"$8 $9 ${10} ${11}" 。
在任何地方都这样做,而不仅仅是在可能不明确的情况下,可以被视为良好的编程实践。这既是为了一致性,也是为了避免像
变量的声明和赋值不带
| 1 | var=10 | 
指派。为了读取变量(换句话说,"展开"变量),必须使用
| 1 2 3 4 | $var      # use the variable ${var} # same as above ${var}bar # expand var, and append"bar" too $varbar # same as ${varbar}, i.e expand a variable called varbar, if it exists. | 
这有时让我感到困惑——在其他语言中,我们以同样的方式引用变量,不管它是在赋值的左边还是右边。但是shell脚本是不同的,
使用
| 1 2 3 | dir=(*)           # store the contents of the directory into an array echo"${dir[0]}" # get the first entry. echo"$dir[0]" # incorrect | 
您还可以在大括号内执行一些文本操作:
| 1 2 | STRING="./folder/subfolder/file.txt" echo ${STRING} ${STRING%/*/*} | 
结果:
| 1 | ./folder/subfolder/file.txt ./folder | 
或
| 1 2 | STRING="This is a string" echo ${STRING// /_} | 
结果:
| 1 | This_is_a_string | 
你在"规则变量"中是对的,不需要…但它对调试和读取脚本更有用。
变量名的结尾通常用空格或换行符表示。但如果在打印变量值后不需要空格或换行符呢?大括号告诉shell解释器变量名的结尾在哪里。
经典示例1)-不带尾随空格的shell变量| 1 2 3 4 5 6 7 | TIME=10 # WRONG: no such variable called 'TIMEsecs' echo"Time taken = $TIMEsecs" # What we want is $TIME followed by"secs" with no whitespace between the two. echo"Time taken = ${TIME}secs" | 
示例2)具有版本化JAR的Java类路径
| 1 2 3 4 5 | # WRONG - no such variable LATESTVERSION_src CLASSPATH=hibernate-$LATESTVERSION_src.zip:hibernate_$LATEST_VERSION.jar # RIGHT CLASSPATH=hibernate-${LATESTVERSION}_src.zip:hibernate_$LATEST_VERSION.jar | 
(弗雷德的回答已经说明了这一点,但他的例子有点抽象)
访问数组元素和执行大括号扩展时总是需要大括号。
最好不要过于谨慎,即使没有歧义的余地,也可以使用
例如:
| 1 2 3 4 5 6 | dir=log prog=foo path=/var/${dir}/${prog} # excessive use of {}, not needed since / can't be a part of a shell variable name logfile=${path}/${prog}.log # same as above, . can't be a part of a shell variable name path_copy=${path} # {} is totally unnecessary archive=${logfile}_arch # {} is needed since _ can be a part of shell variable name | 
因此,最好将这三行写成:
| 1 2 3 | path=/var/$dir/$prog logfile=$path/$prog.log path_copy=$path | 
这绝对是更可读的。
见:
- Linux环境变量名中允许的字符
根据Sierrax和Peter关于文本操作的建议,使用大括号
假设您有一个sposi.txt文件,其中包含一本意大利Weel已知小说的第一行:
| 1 2 | > sposi="somewhere/myfolder/sposi.txt" > cat $sposi | 
输出:
现在创建两个变量:
| 1 2 3 4 5 | # Search the 2nd word found in the file that"sposi" variable points to > word=$(cat $sposi | cut -d"" -f 2) # This variable will replace the word > new_word="filone" | 
现在用sposi.txt文件中的一个新单词替换单词变量内容。
| 1 2 | > sed -i"s/${word}/${new_word}/g" $sposi > cat $sposi | 
输出:
单词"ramo"已被替换。