我们什么时候需要围绕shell变量的花括号?

问题描述 投票:559回答:7

在shell脚本中,我们何时在扩展变量时使用{}

例如,我见过以下内容:

var=10        # Declare variable

echo "${var}" # One use of the variable
echo "$var"   # Another use of the variable

是否存在显着差异,还是只是风格?一个比另一个更受欢迎吗?

bash shell syntax curly-braces
7个回答
657
投票

在这个特定的例子中,它没有任何区别。但是,如果你想在字符串中扩展变量{}${}中的foo很有用

"${foo}bar"

因为"$foobar"会扩展由foobar确定的变量。

在以下情况下无条件地需要使用花括号:

  • 扩展数组元素,如${array[42]}
  • 使用参数扩展操作,如${filename%.*}(删除扩展名)
  • 将位置参数扩展到9以上:"$8 $9 ${10} ${11}"

在任何地方这样做,而不仅仅是在可能模糊的情况下,可以被认为是良好的编程实践。这既是为了保持一致性,也是为了避免像$foo_$bar.jpg这样的意外,因为下划线成为变量名称的一部分并不明显。


116
投票

变量是在没有$且没有{}的情况下声明和分配的。你必须使用

var=10

分派。为了从变量中读取(换句话说,'展开'变量),必须使用$

$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脚本不同,$var=10不会做你想象的那样!


30
投票

您使用{}进行分组。大括号需要取消引用数组元素。例:

dir=(*)           # store the contents of the directory into an array
echo "${dir[0]}"  # get the first entry.
echo "$dir[0]"    # incorrect

26
投票

您还可以在大括号内进行一些文本操作:

STRING="./folder/subfolder/file.txt"
echo ${STRING} ${STRING%/*/*}

结果:

./folder/subfolder/file.txt ./folder

要么

STRING="This is a string"
echo ${STRING// /_}

结果:

This_is_a_string

你是正确的“常规变量”是不需要的...但它对调试和阅读脚本更有帮助。


11
投票

变量名称的结尾通常用空格或换行符表示。但是如果我们在打印变量值后不想要空格或换行符怎么办?花括号告诉shell解释器变量名称的结尾。

Classic Example 1) - shell variable without trailing whitespace

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类路径

# 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

(弗雷德的回答已经说明了这一点,但他的例子有点过于抽象)


2
投票

根据SierraX和Peter关于文本操作的建议,使用大括号{}将变量传递给命令,例如:

假设您有一个sposi.txt文件,其中包含意大利着名小说的第一行:

> sposi="somewhere/myfolder/sposi.txt"
> cat $sposi

输出:qazxsw poi

现在创建两个变量:

quel ramo del lago di como che volge a mezzogiorno

现在用sposi.txt文件中的new_word替换单词变量内容

# 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"

输出:qazxsw poi

“ramo”这个词已被取代。


1
投票

总是需要使用花括号来访问数组元素并进行支撑扩展。

不要过于谨慎并使用> sed -i "s/${word}/${new_word}/g" $sposi > cat $sposi 进行shell变量扩展是件好事,即使没有模棱两可的余地。

例如:

quel filone del lago di como che volge a mezzogiorno

因此,最好将三行写为:

{}

这肯定更具可读性。

由于变量名不能以数字开头,因此shell不需要围绕编号变量的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 (如path=/var/$dir/$prog logfile=$path/$prog.log path_copy=$path {}等),除非这样的扩展后跟一个数字。这太微妙了,它确实在这种情况下明确使用$1

$2

看到:

  • {}
© www.soinside.com 2019 - 2024. All rights reserved.