【问题标题】:/bin/sh: Odd string comparison error 'unexpected operator' [duplicate]/bin/sh:奇数字符串比较错误“意外运算符”[重复]
【发布时间】:2014-11-08 21:15:23
【问题描述】:

发现这个错误很奇怪,因为以前我的脚本正在运行,但是在我将它从我正在处理的服务器上移到我的本地计算机后,它停止了工作,只是给了我一个“意外的操作员”错误。

# Else if the script is being run in the arrayscripts directory, add /output/ ...
elif [ $basePath == "arrayscripts" ];
then
        echo "$dscr has started to run."
        cpuPath="`pwd`/output/cpu.binary"
        txtPath="`pwd`/output/cpu.txt"
        csvPath="`pwd`/output/cpu.csv"

【问题讨论】:

  • 您可能使用 POSIX shell 运行它,可能是 dash(在 Ubuntu 中默认为 sh),它不支持 ==。见Bashisms
  • 如果这个 shell 是 bash,明显的问题是缺少引号。 "$basePath"$basePath 不一样——不带引号,后者可以扩展为任意数量的参数,这使得它放在运算符位置的内容完全不可预测。
  • 既然你标记了这个bash,你的脚本是用#!/bin/bash 开始的吗?如果没有,您应该这样做。
  • @CharlesDuffy 以 #!/bin/sh 开头以为是 bash,抱歉标记错误
  • 仅供参考,使用`pwd` 的效率远低于$PWD

标签: shell sh


【解决方案1】:

如果您的实际 shell 是 /bin/sh [与最初的问题相反,但讨论评论已明确],请在测试表达式中使用 = 而不是 ==

elif [ "$basePath" = arrayscripts ]

请注意,在这种情况下,右侧不需要引用,因为它不包含扩展和语法敏感字符。


或者,如果在使用 bash 时这个问题可以重现,那么明显的问题是缺少引号。

使用任一

[ "$basePath" = arrayscripts ] # this is POSIX compatible

[[ $basePath = arrayscripts ]] # this works only with bash

否则,$basePath 扩展成的参数数量是未定义的——它可能扩展成零个参数,从而使语句

[ = arrayscripts ]

...它会尝试使用= 作为一元运算符,但它不是...

或者如果$basePath 包含"true -o bar =",它可以扩展为类似

[ true -o bar = arrayscripts ]

...导致程序行为与您实际想要的非常不同。


底线:当编写遵循 POSIX 规则的 shell(基本上,除了 zsh 或 fish 之外的任何东西)时,引用你的扩展,除非你有一个特定的和令人信服的理由不这样做。 (使用 bash/ksh 扩展 [[ ]] 提供了这样一个原因,通过引入不发生扩展结果的字符串拆分和全局扩展的上下文。

【讨论】:

  • 为了完整起见,我想我会提到引用不会阻止 [ = arrayscripts ] 情况。似乎推荐的是使用 [ ".$basePath" = .arrayscripts ] 这样如果 basePath 未定义,则剩下 [ 。 = .arrayscripts ].
  • @bobpaul,该声明不正确:[ "" = arrayscripts ] -- [ "$emptyvar" = arrayscripts ] 计算结果 -- 不是语法错误;在任何符合 POSIX 的 shell 中,它都能正确地将左侧的空字符串与右侧的非空字符串进行比较。
  • @bobpaul, ...你可以自己测试一下:运行[ "$emptyvar" = arrayscripts ],并注意没有向标准错误报告任何语法错误。
【解决方案2】:

如果您使用诸如dash 之类的 POSIX shell 执行脚本,则会出现此错误。 dash 是某些平台(例如 Ubuntu 和 Debian)上的默认 /bin/sh

== 特定于 bash ( Bashism ),与 dash 等 POSIX shell 不兼容,后者仅使用 = 来测试字符串是否相等。

在单括号的上下文中,===bash 中被视为同一个运算符,因此可以使用其中任何一个。

【讨论】:

  • 感谢您告诉我,更新了标签,因此我包含了我正在使用的操作系统 Ubuntu
  • @MOS182,更重要的是当你的 shell 实际上是 sh 时停止标记它 bash
  • 请注意,尽管bash[ ... ] 中支持==,但实际上没有理由这样做。请改用[[ ... == ... ]]
【解决方案3】:

按照 'alister' 在 unix 和 linux 论坛 (http://www.unix.com/shell-programming-and-scripting/141856-how-avoid-unexpected-operator-error-when-comparing-2-strings.html) 中的建议,我设法通过将比较函数从 '==' 更改为 '=' 来让我的脚本工作,所以我的脚本看起来像这样

# Else if the script is being run in the arrayscripts directory, add /output/ ...
    elif [ "$basePath" = "arrayscripts" ];
    then
            echo "$dscr has started to run."
            cpuPath="`pwd`/output/cpu.binary"
            txtPath="`pwd`/output/cpu.txt"
            csvPath="`pwd`/output/cpu.csv"

希望如果有人遇到和我一样的错误,这个答案会帮助他们。 .

【讨论】:

  • 你同时发布了问题和答案。而且由于您标记为BASH,您的回答也是错误的。
  • Bash 对 = and == 的处理方式相同。来自man bashThe = operator is equivalent to ==
  • @anubhava 为什么我的回答错了?
  • @JohnB:已经在他的评论中回答了你的问题。
  • @anubhava John 说过 = 和 == 被同等对待,在这种情况下,我的回答怎么错了?为什么当它是 == 而不是 = 时出现错误?
猜你喜欢
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 2019-12-11
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多