【问题标题】:Syntax error running command bc under bash 4.1bash 4.1下运行命令bc的语法错误
【发布时间】:2014-12-26 20:03:36
【问题描述】:

我有一个带有以下行的 bash 脚本。变量start_timestart_files[$i] 是浮点数。我想使用命令bc 比较它们,如下所示:

result1=$(bc -l <<< $start_time'>='${start_files[$i]})

当我运行脚本时,我总是收到以下错误。

(standard_in) 1: syntax error

我已经检查过这个错误是由这一行引起的。我究竟做错了什么?我在使用 bash 4.1 时发生这种情况,而 bash 4.3 运行良好。但是我需要使用 bash 4.1 运行脚本。

bc 命令有效,但输入无效。使用此命令从文件中读取变量start_files

IFS=, read -r -a start_files <<< $(head -n 1 file.txt)

基本上我想从第一行读取所有值,用逗号分隔并将它们存储到数组的不同位置。然而,使用 bash 4.1,所有值最终都存储在 start_files[0] 中。我该如何解决这个问题?此行适用于 bash 4.3

【问题讨论】:

  • 这些变量的值是多少?
  • 浮点值,如 9.5、4.2、34.5678 等
  • 使用bash -x script 调试脚本时看到了什么?它通常有助于告诉您哪里出了问题。但是,它不会打印 here 字符串,因此您必须修改脚本以执行 echo "bc -l &lt;&lt;&lt; $start_time &gt;= ${start_files[$i]}" 或类似的操作,以准确反映将要执行的内容,以便查看 bc 抱怨的输入。在解决语法错误问题时,首先需要看到的是被投诉的语法。
  • 抱歉,我无法使用 bash 版本 4.1.2 (RHEL 6) 重现该错误:start_time=9.5; i=4; start_files[$i]=4.2; result1=$(bc -l &lt;&lt;&lt; $start_time'&gt;='${start_files[$i]}); echo $result1
  • @KoTy,检查 specific 值是否真的是你认为的那样——一个错误导致其中一个为空,f'rinstance,很可能这个错误的原因。在运行bc 之前立即回显它们;如果不这样做,因为这是 bc 语法错误而不是 bash 语法错误,这意味着我们根本没有足够的信息来提供帮助。

标签: bash scripting bc


【解决方案1】:

我建议你使用双引号:

result1=$(bc -l <<<"$start_time >= ${start_files[$i]}")

这样,您将一个字符串回显到bc,其中包含您的变量。

【讨论】:

  • 一直给我同样的错误,(standard_in)1:语法错误
  • 如果不知道变量的值,就不可能说出原因。也许你应该使用set -x,这样你就可以看到导致你的错误的值是什么。
  • @koty 一定是值:echo "&gt;&gt;$start_time &gt;= ${start_files[$i]}&lt;&lt;" 向您展示了什么
【解决方案2】:

您是否正在从具有 DOS 风格行尾的文件中读取值?

$ start_time=$'1.5\r'
$ i=1
$ start_files[$i]=$'2.5\r'
$ bc -l <<< "$start_time >= ${start_files[$i]}"
(standard_in) 1: illegal character: ^M
(standard_in) 1: illegal character: ^M

【讨论】:

    【解决方案3】:

    您可以避免使用 here-string,添加双引号并删除 $:

    result1=$(echo "$start_time >= ${start_files[i]}" | bc -l)
    

    【讨论】:

      【解决方案4】:

      提供您正在使用的bc 的版本会有所帮助。我猜这在两个系统上是不一样的。顺便说一句,您的错误与 Bash 无关。

      POSIX bc 明确指出比较(在POSIX' bc Specification 中称为relational_expression 只能出现在whileforif 构造中。

      所以,你首先要尝试的是:

      bc <<< "if($start_time >= ${start_files[$i]}) 1 else 0"
      

      这可能不起作用,因为 POSIX'bc不允许在 if 语句中使用 else 子句。 (尽管看起来很神奇,但您正确地阅读了最后一句话)。

      如果您的 bc 真的是 POSIX 卡住了,那么您将不得不做一些丑陋的事情,例如,

      bc <<< "ret=0; if($start_time >= ${start_files[$i]}) { ret=1 } ret"
      

      甚至更糟的东西(抱歉,我这里没有 POSIX bc,所以我无法进行实验——如果有人手头有一个或记得他头顶上的语法,请编辑此行使用正确的语法)。

      祝你好运!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多