【问题标题】:bash - commands in variables with pipesbash - 带有管道的变量中的命令
【发布时间】:2022-11-04 17:40:06
【问题描述】:

有人可以解释为什么A 和B 的行为不同吗?

A=`echo hello how are you | wc -w`

和

CMD="echo hello how are you | wc -w"
B=`$CMD`

他们给出不同的结果:

$echo $A
4

$echo $B
hello how are you | wc -w

我想要的是一个变量中的命令,我可以在脚本的几个点执行它并获取不同的值进行比较。它曾经工作正常,但如果命令有管道,它就不起作用。

【问题讨论】:

标签: bash pipe command-substitution


【解决方案1】:
  • ``(即反引号)或 $() 在 bash 中称为命令替换.
  • "" - 例如使用保留字符的文字值,即数据。
  1. 在您的第一个示例中,执行命令 echo hello how are you | wc -w,并将其值 4 分配给 A,因此您得到 4。

  2. 在您的第二个示例中,它将字符串分配给变量 B 并且由 `$CMD` | 未“评估”因为分词较晚(有关更多信息,请参阅here),您将获得hello how are you | wc -w。

    你需要的可以用eval命令来完成,如下:

    CMD="echo hello how are you | wc -w"
    echo `eval $CMD`            # or just eval "$CMD"
    # Output is 4
    

【讨论】:

  • 将字符串分配给变量 B 并且 $CMD 其值未被“评估”--> 如果是这样,那么B 将等于“echo hello how are you | wc -w”,但不是:它等于“hello how are you | wc -w”。所以echo 命令曾是执行。它只是没有进入wc。
  • @k314159 调整了我的答案。
  • 我仍然不明白运行 echo 而不是管道背后的逻辑是什么......但是感谢您提供 eval 解决方案!
  • @MartinMassera 由于“后期分词”它未评估的管道,请参阅unix.stackexchange.com/a/388352/393118 了解更多信息。我也将链接添加到我的答案中。
  • 使用引号很重要——eval "$CMD",而不是eval $CMD。否则,如果您的字符串单词拆分以包含任何 glob,则您可以将文件名注入代码中。
猜你喜欢
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多