【问题标题】:Difference between ${} and $() in Bash [duplicate]Bash中${}和$()之间的区别[重复]
【发布时间】:2015-02-12 20:52:42
【问题描述】:

我有两个问题,需要一些帮助来理解它们。

  1. ${}$() 有什么区别?我明白() 表示在单独的 shell 中运行命令并放置 $ 表示通过 变量的值。有人可以帮助我理解 这?如果我错了,请纠正我。

  2. 如果我们可以使用for ((i=0;i<10;i++)); do echo $i; done 并且它工作正常,那么为什么我不能将它用作while ((i=0;i<10;i++)); do echo $i; done?两者的执行周期有何不同?

【问题讨论】:

  • 这是一个两部分的问题。 “反引号与大括号”恰好对两者都有答案?如果答案为 1,请让 OP 对其进行编辑,使其成为标准的单数问题。

标签: linux bash scripting


【解决方案1】:

语法是令牌级别的,因此美元符号的含义取决于它所在的令牌。表达式$(command)`command` 的现代同义词,代表命令替换;这意味着运行command 并将其输出放在这里。所以

echo "Today is $(date). A fine day."

将运行date 命令并将其输出包含在echo 的参数中。括号与在子 shell 中运行命令的语法无关,尽管它们有一些共同点(命令替换也在单独的子 shell 中运行)。

相比之下,${variable} 只是一种消歧机制,所以当你表示变量 var 的内容时,你可以说 ${var}text,然后是 text(而不是 $vartext 表示内容变量vartext)。

while 循环需要一个参数,该参数的计算结果应为真或假(或实际上是多个,其中检查最后一个的真值 - 感谢 Jonathan Leffler 指出这一点);当它为假时,循环不再执行。 for 循环遍历项目列表并将每个项目依次绑定到一个循环变量;您所指的语法是一种(相当笼统的)在一系列算术值上表示循环的方法。

像这样的for 循环可以改写为while 循环。表达式

for ((init; check; step)); do
    body
done

等价于

init
while check; do
    body
    step
done

为了便于阅读,将所有循环控制放在一个地方是有意义的;但正如你所看到的,当它像这样表达时,for 循环比while 循环做得更多。

当然,这种语法是特定于 Bash 的;经典的 Bourne shell 只有

for variable in token1 token2 ...; do

(更优雅的是,您可以避免第一个示例中的echo,只要您确定您的参数字符串不包含任何% 格式代码:

date +'Today is %c. A fine day.'

尽可能避免一个过程是一个重要的考虑因素,即使在这个孤立的示例中它并没有太大的区别。)

【讨论】:

  • 严格来说,while 命令需要一个命令序列(不一定是管道),序列中最后一个命令的退出状态决定了循环是否继续。因此:while ls; pwd; date; do echo Hi; sleep 1; done 有效,date 的退出状态控制循环是否继续。我使用分号是因为您不能在注释中格式化换行符,但您可以在 shell 脚本中将命令写在多行上。
  • 我很惊讶这个答案继续得到支持;它不是特别出色。如果您对此表示赞同,您是否愿意解释其中的哪一部分有用?我猜for 循环和while 循环之间的关系并不完全明显(我记得当我第一次阅读 Perl Camel Book 的第一版时喜欢它) 但在那里除此之外……?
  • 还有“嗯,其他两个答案也不好”的问题。
  • @JonathanLeffler Heh,也许就放弃投票吧(-:
  • @tripleee 为什么不想要点赞?无论如何,我经常投票赞成答案,因为如果它们有帮助(在这种情况下,我需要知道 $() 和 ${} 之间的区别),无论它们是否是 stellar...
【解决方案2】:
  1. $() 表示:“先评估这个,然后再评估该行的其余部分”。

    例如:

    echo $(pwd)/myFile.txt
    

    将被解释为

    echo /my/path/myFile.txt
    

    另一方面,${} 扩展了一个变量。

    例如:

    MY_VAR=toto
    echo ${MY_VAR}/myFile.txt
    

    将被解释为

    echo toto/myFile.txt
    
  2. 为什么我不能用bash$ while ((i=0;i<10;i++)); do echo $i; done

    恐怕答案是 while 的 bash 语法与 for 的语法不同。

【讨论】:

  • “先评估这个,然后再评估该行的其余部分”——我不明白$(...)的这个描述。
【解决方案3】:
  1. 您的理解是正确的。有关 {} 的详细信息,请参阅 bash ref - parameter expansion

  2. 'for' 和 'while' 具有不同的语法,并为迭代提供不同样式的程序员控制。大多数非 asm 语言都提供类似的语法。

有了while,你可能会写i=0; while [ $i -lt 10 ]; do echo $i; i=$(( i + 1 )); done,本质上是自己管理迭代的一切

【讨论】:

  • 不是我的反对票,但 OP 似乎将 (command …)$(commnd …) 混淆了,尽管它们也有一些共同点,但它们在细节上却大不相同。因此,您的第一次观察并不完全准确。 OP的理解并不完全正确。
  • 大多数非 asm 语言都提供类似的语法。 什么???
  • @gniourf_gniourf FOR 语法。在大多数非汇编语言中(据我所知),不包括像 algol 这样的古老语言
  • @JonathanLeffler 感谢您的澄清。我也这么认为,但认为在上下文中 OP 并不意味着子外壳。
猜你喜欢
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
  • 1970-01-01
  • 2021-12-17
  • 2017-04-26
相关资源
最近更新 更多