bash 我们什么时候需要在 shell 变量周围使用花括号?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8748831/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When do we need curly braces around shell variables?
提问by New User
In shell scripts, when do we use {}
when expanding variables?
在shell脚本中,我们{}
什么时候在扩展变量时使用?
For example, I have seen the following:
例如,我看到了以下内容:
var=10 # Declare variable
echo "${var}" # One use of the variable
echo "$var" # Another use of the variable
Is there a significant difference, or is it just style? Is one preferred over the other?
是否有显着差异,或者只是风格?一个比另一个更受欢迎吗?
回答by Fred Foo
In this particular example, it makes no difference. However, the {}
in ${}
are useful if you want to expand the variable foo
in the string
在这个特定的例子中,它没有区别。但是,如果您想扩展字符串中的变量,则{}
in${}
很有用foo
"${foo}bar"
since "$foobar"
would instead expand the variable identified by foobar
.
因为"$foobar"
会扩展由 标识的变量foobar
。
Curly braces are also unconditionally required when:
在以下情况下也无条件地需要花括号:
- expanding array elements, as in
${array[42]}
- using parameter expansion operations, as in
${filename%.*}
(remove extension) - expanding positional parameters beyond 9:
"$8 $9 ${10} ${11}"
- 扩展数组元素,如
${array[42]}
- 使用参数扩展操作,如
${filename%.*}
(删除扩展) - 扩展位置参数超过 9:
"$8 $9 ${10} ${11}"
Doing this everywhere, instead of just in potentially ambiguous cases, canbe considered good programming practice. This is both for consistency and to avoid surprises like $foo_$bar.jpg
, where it's not visually obvious that the underscore becomes part of the variable name.
在任何地方都这样做,而不仅仅是在潜在的模棱两可的情况下,可以被认为是良好的编程实践。这既是为了保持一致性,也是为了避免意外,比如$foo_$bar.jpg
下划线成为变量名称的一部分在视觉上并不明显。
回答by Aaron McDaid
Variables are declared and assigned without $
and without {}
. You have to use
变量在没有$
和没有的情况下声明和分配{}
。你必须使用
var=10
to assign. In order to read from the variable (in other words, 'expand' the variable), you must use $
.
分派。为了从变量中读取(换句话说,“扩展”变量),您必须使用$
.
$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.
This has confused me sometimes - in other languages we refer to the variable in the same way, regardless of whether it's on the left or right of an assignment. But shell-scripting is different, $var=10
doesn't do what you might think it does!
这有时让我感到困惑 - 在其他语言中,我们以相同的方式引用变量,无论它是在赋值的左侧还是右侧。但是 shell 脚本是不同的,$var=10
它不会像你想象的那样做!
回答by glenn Hymanman
You use {}
for grouping. The braces are required to dereference array elements. Example:
您{}
用于分组。需要大括号来取消引用数组元素。例子:
dir=(*) # store the contents of the directory into an array
echo "${dir[0]}" # get the first entry.
echo "$dir[0]" # incorrect
回答by SierraX
You are also able to do some text manipulation inside the braces:
您还可以在大括号内进行一些文本操作:
STRING="./folder/subfolder/file.txt"
echo ${STRING} ${STRING%/*/*}
Result:
结果:
./folder/subfolder/file.txt ./folder
or
或者
STRING="This is a string"
echo ${STRING// /_}
Result:
结果:
This_is_a_string
You are right in "regular variables" are not needed... But it is more helpful for the debugging and to read a script.
您是对的,不需要“常规变量”......但它对调试和阅读脚本更有帮助。
回答by Sridhar Sarnobat
The end of the variable name is usually signified by a space or newline. But what if we don't want a space or newline after printing the variable value? The curly braces tell the shell interpreter where the end of the variable name is.
变量名的结尾通常由空格或换行符表示。但是如果我们在打印变量值后不想要空格或换行符怎么办?花括号告诉 shell 解释器变量名的结尾在哪里。
Classic Example 1) - shell variable without trailing whitespace
经典示例 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"
Example 2) Java classpath with versioned jars
示例 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
(Fred's answer already states this but his example is a bit too abstract)
(弗雷德的回答已经说明了这一点,但他的例子有点太抽象了)
回答by codeforester
Curly braces are always needed for accessing array elements and carrying out brace expansion.
访问数组元素和执行大括号扩展总是需要大括号。
It's good to be not over-cautious and use {}
for shell variable expansion even when there is no scope for ambiguity.
{}
即使没有歧义,也不要过度谨慎并用于 shell 变量扩展。
For example:
例如:
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
So, it is better to write the three lines as:
因此,最好将三行写为:
path=/var/$dir/$prog
logfile=$path/$prog.log
path_copy=$path
which is definitely more readable.
这绝对更具可读性。
Since a variable name can't start with a digit, shell doesn't need {}
around numbered variables (like $1
, $2
etc.) unless such expansion is followed by a digit. That's too subtle and it does make to explicitly use {}
in such contexts:
由于变量名称不能以数字开头,壳不需要{}
围绕编号的变量(如$1
,$2
等),除非这样的膨胀被后跟数字。这太微妙了,它确实可以{}
在这种情况下明确使用:
set app # set to app
fruit=le # sets fruit to apple, but confusing
fruit=le # sets fruit to apple, makes the intention clear
See:
看:
回答by Fabio Natalini
Following SierraX and Peter's suggestion about text manipulation, curly brackets {}
are used to pass a variable to a command, for instance:
遵循 SierraX 和 Peter 关于文本操作的建议,大括号{}
用于将变量传递给命令,例如:
Let's say you have a sposi.txtfile containing the first line of a well-known Italian novel:
假设您有一个sposi.txt文件,其中包含一部著名的意大利小说的第一行:
> sposi="somewhere/myfolder/sposi.txt"
> cat $sposi
Ouput: quel ramo del lago di como che volge a mezzogiorno
输出: quel ramo del lago di como che volge a mezzogiorno
Now create two variables:
现在创建两个变量:
# 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"
Now substitute the wordvariable content with the one of new_word, inside sposi.txt file
现在用sposi.txt 文件中的new_word替换单词变量 content
> sed -i "s/${word}/${new_word}/g" $sposi
> cat $sposi
Ouput: quel filone del lago di como che volge a mezzogiorno
输出: quel filone del lago di como che volge a mezzogiorno
The word "ramo" has been replaced.
“ramo”一词已被替换。