什么时候需要在外壳变量周围花括号?

Shell脚本中,何时在扩展变量时使用{}

例如,我看到了以下内容:

var=10        # Declare variable

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

是否存在重大差异,还是仅仅是样式? 是一个比另一个更好的选择吗?


#1楼

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

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

结果:

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

要么

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

结果:

This_is_a_string

您是正确的,不需要“常规变量” ...但是它对于调试和阅读脚本更有用。


#2楼

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

经典示例1)-没有尾随空格的shell变量

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

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


#3楼

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

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

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

quel ramo del lago di como che volge a mezzogiorno

现在创建两个变量:

# 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文件中的word变量内容替换为new_word之一

> sed -i "s/${word}/${new_word}/g" $sposi
> cat $sposi

quel filone del lago di como che volge a mezzogiornoquel filone del lago di como che volge a mezzogiorno

“ ramo”一词已被替换。


#4楼

访问数组元素和执行括号扩展始终需要弯括号。

最好不要过于谨慎,即使在没有歧义的情况下,也可以使用{}进行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

绝对更易读。

由于变量名不能以数字开头,因此shell不需要在数字变量(例如$1$2等)周围使用{} ,除非在此扩展名后跟随数字。 这太微妙了,确实可以在以下情况下显式使用{}

set app      # set $1 to app
fruit=$1le   # sets fruit to apple, but confusing
fruit=${1}le # sets fruit to apple, makes the intention clear

看到:


#5楼

在此特定示例中,没有区别。 然而, {}${}如果你想扩展变量是有用的foo字符串中

"${foo}bar"

因为"$foobar"会改为扩展foobar标识的变量。

在以下情况下,也无条件需要大括号:

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

在所有地方(而不只是在可能含糊的情况下)执行此操作可以被视为良好的编程习惯。 这既是为了保持一致性,又是为了避免出现类似$foo_$bar.jpg类的意外$foo_$bar.jpg ,下划线在视觉上并不明显成为变量名的一部分。


#6楼

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

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并没有达到您的想象!


#7楼

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值