【问题标题】:bash variable being passed to external program (bc) as string? [duplicate]bash 变量作为字符串传递给外部程序(bc)? [复制]
【发布时间】:2019-09-22 21:50:43
【问题描述】:

我有一个带有以下内容的 shell 脚本:

    filesize=22
    incommon=25
    num=$(bc <<< 'scale=2; ($incommon / $filesize) * 100')

输出:

(standard_in) 1:非法字符:$

(standard_in) 1:非法字符:$

例如,如果我将 ($incommon / $filesize) 替换为 (22 / 55),它就可以正常工作。 在这种情况下,如何将变量传递给 bc?

【问题讨论】:

  • 切换到引号。

标签: bash shell bc


【解决方案1】:

bash 将单引号(撇号 ')括起来的单词视为 字面意思。

也就是说,

$ filesize=22
$ incommon=25
$ printf "%s\n" 'scale=2; ($incommon / $filesize) * 100)'
scale=2; ($incommon / $filesize) * 100)

在双引号 (") 内,bash 会特别对待这些字符:

  • 反引号 (`)
  • 美元符号 ($)
  • 反斜杠 (\)
  • 有时感叹号 (!)

你想要:

$ printf "%s\n" "scale=2; ($incommon / $filesize) * 100)"
scale=2; (25 / 22) * 100)

具体来说:

$ filesize=22
$ incommon=25
$ num="$(bc <<< "scale=2; ($incommon / $filesize ) * 100")"
$ printf "%s\n" "$num"
113.00

【讨论】:

    【解决方案2】:

    您可以改为使用以下命令:

    num=$(echo "scale=2; ($incommon/$filesize) * 100" | bc )
    

    正如 Charles 所建议的,这可以通过从 ' 切换到 " 引号来完成。

    num=$(bc <<< "scale=2; ($incommon / $filesize) * 100")
    

    【讨论】:

    • 唯一重要的区别(为了回答OP的问题)是单引号和双引号之间的区别。使用管道实际上使这个 slower 比 OP 的原始代码(foo &lt;&lt;&lt;"bar" 创建一个带有bar 的临时文件,并从该文件重定向foo 的标准输入;在现代系统上@ 987654328@ 挂载了一个内存文件系统,这比fork() 将一个子shell 放在管道的左侧要便宜,正如这个答案的初始修订版所暗示的那样)。
    • @CharlesDuffy 非常感谢您的解释。引号是这里的唯一原因。
    猜你喜欢
    • 2020-06-16
    • 1970-01-01
    • 2020-01-28
    • 2019-03-14
    • 2020-04-15
    • 2020-06-30
    • 1970-01-01
    • 2019-02-16
    • 2019-07-13
    相关资源
    最近更新 更多