【问题标题】:Using operators on strings in sh在 sh 中对字符串使用运算符
【发布时间】:2014-11-11 04:54:42
【问题描述】:

我有一个 shell 脚本来检查 Debian 安装是否存在 heartbleed 漏洞。它首先获取任何已安装的面向 SSL 的软件包的版本号列表:

$: dpkg -l | grep ssl | grep amd64 | awk '{print $3}'
1.0.1e-2+deb7u3
1.0.1e-2+deb7u3
1.0.1e-2+deb7u3

这用于for 循环以确定版本号是否在具有 1.0.1e-2+deb7u6 或更高版本的固定版本之前:

#!/bin/sh
heartbleed_is_fixed() {
    #
    # For each package that uses SSL
    for version in $(dpkg -l | grep ssl | grep amd64 | awk '{print $3}'); do
        #
        # The heartbleed bug was fixed in OpenSSL 1.0.1e2+deb7u6
        # Check each package and if package version is less
        if [[ "$version" < "1.0.1e-2+deb7u6" ]]; then
            #
            # return false, heartbleed is not fixed
            return 1
        fi
    done
    #
    # If we got to this point then the heartbleed bug has been fixed
    return 0
}

这个在 bash 中运行良好,但是这个脚本需要在 sh 中运行。在 sh 中运行时,它偶然发现了 if 语句中的表达式:“无法打开 1.0.1e-2+deb7u6:没有这样的文件”。它指示 if 语句的行号,因此显然将 &lt; 运算符误解为输入流指令:

"$version" < "1.0.1e-2+deb7u6"

编辑:双方括号([[]])也会在 sh: "[[: not found" 中导致错误,但 bash 需要双括号才能正确计算表达式。

如何调整此脚本以使其在 sh 中工作?

【问题讨论】:

  • 尝试使用-lt 作为“小于”运算符而不是&lt;。现在,&lt; 被解释为 I/O 重定向。
  • @rje 是个好主意,但 -lt 是数字表达式的布尔运算符,而不是字符串;它返回“非法数字:1.0.1e-2+deb7u3”
  • 啊,是的,当然,我错了。你想做一个字符串比较。对不起:)

标签: linux string bash shell sh


【解决方案1】:

首先,这里没有布尔运算符。布尔运算符(例如:and、or)应该作用于布尔值,而不是字符串。

sh 中,没有[[,所以你需要旧的[

你必须逃脱&lt;

if [ "$version" \< "1.0.1e-2+deb7u6" ]; then

您也可以使用"&lt;"'&lt;',只要确保它被转义即可。

【讨论】:

  • 谢谢,我会编辑问题以引用逻辑运算符,然后我会尝试你的解决方案!
  • 非常正确;它第一次起作用。我以一种非常特别的方式学习了 shell 脚本 - 如果你能推荐任何能帮助我解决这类问题的资源,我将非常感激!
  • bash 手册 + 常见问题解答 mywiki.wooledge.org/BashFAQ 。首先,了解如何解析一行,什么是引用和转义,什么是命令及其参数。大多数问题是由于误解或不了解该语言的基础知识造成的。
猜你喜欢
  • 2017-06-20
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
  • 2011-07-27
  • 2012-11-29
  • 2020-04-24
  • 2019-03-19
相关资源
最近更新 更多