88

当我回答这个问题时,我打算使用这个${}符号,因为我在这里见过很多次,所以它比反引号更可取。

但是,当我尝试

joulesFinal=${echo $joules2 \* $cpu | bc}

我收到了消息

-bash: ${echo $joules * $cpu | bc}: bad substitution

joulesFinal=`echo $joules2 \* $cpu | bc`

工作正常。那么我还需要进行哪些其他更改?

4

3 回答 3

131

称为命令替换,当您使用 (花括号) 时,它等效于 (括号`` ) 。$()${}

所以所有这些表达式都是相等的,意思是“解释放置在里面的命令”:

joulesFinal=`echo $joules2 \* $cpu | bc`
joulesFinal=$(echo $joules2 \* $cpu | bc)
#            v                          v
#      ( instead of {                   v
#                                 ) instead of }

While${}表达式用于变量替换。

但是请注意,反引号已被弃用,而$()与 POSIX 兼容,因此您应该更喜欢后者。


来自man bash

命令替换允许命令的输出替换命令名称。有两种形式:

          $(command)
   or
          `command`

此外,``更难处理,例如,您不能嵌套它们。请参阅下面的评论以及为什么 $(...) 优于...(反引号)?.

于 2014-03-28T09:56:31.067 回答
38

在特定情况下,它们的行为略有不同:

$ echo "`echo \"test\" `"
test

$ echo "$(echo \"test\" )"
"test"

所以反引号会默默地删除双引号。

于 2016-05-02T08:53:31.283 回答
2

${}参考 Shell 参数扩展。手册链接:https ://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

'$' 字符引入了参数扩展、命令替换或算术扩展。要扩展的参数名称或符号可以用大括号括起来,这是可选的,但用于保护要扩展的变量免受紧随其后的字符的影响,这些字符可以解释为名称的一部分。

当使用大括号时,匹配的结束大括号是第一个没有被反斜杠转义的“}”,也没有在带引号的字符串中,也没有在嵌入的算术扩展、命令替换或参数扩展中。

FULLPATH=/usr/share/X11/test.conf_d/sk-synaptics.conf
 echo ${FULLPATH##*/}
echo ${FILENAME##*.}

第一个 echo 将获取文件名。第二个将根据手动${parameter##word}部分获得文件扩展名。


$(command)

`command`

请参阅命令替换。

Bash 通过在子 shell 环境中执行命令并将命令替换替换为命令的标准输出来执行扩展,并删除任何尾随的换行符。

https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html

于 2021-12-18T10:36:55.067 回答