【问题标题】:Bash script creates a file which it shouldn't beBash 脚本创建了一个不应该存在的文件
【发布时间】:2018-01-20 07:19:39
【问题描述】:

以下脚本将创建一个名为“Happy”的文件,我不知道为什么,有人可以试试这个脚本并告诉我发生了什么吗? 谢谢!

#!/bin/bash

str1=""
str2="Sad"
str3="Happy"

if [ "$str2">"$str3" ]
    then echo "$str2 is greater than $str3"
elif [ "$str2"<"$str3" ]
    then echo "$str2 is less than $str3"
fi

【问题讨论】:

  • 请看:shellcheck.net
  • 您将命令 $str2 的输出重定向到名为 $str3 的文件。 &gt; 在这种情况下不是比较而是重定向。
  • @Cyrus 感谢链接,它自动发现问题,好工具

标签: bash output-redirect


【解决方案1】:

[ 只是test 命令的(愚蠢的)别名;它后面的所有内容(包括强制关闭])都是一个论点。 (你拥有的和if test "$str2"&gt;"$str3"一样对待。)

有两个问题:

  1. 操作数和运算符需要用空格隔开。

    # still not quite right, but ...
    if [ "$str2" > "$str3" ]
    
  2. 由于&gt;&lt; 被Shell 解释为重定向运算符,因此必须对它们进行转义,以便将它们作为参数传递给[

    if [ "$str2 \> "$str3" ]
    

(您可能认为只转义运算符就足够了;但是,"$str2"\&gt;"$str3" 将被视为test 的单个字符串参数,而不是test 将解释为表达式的三个单独参数。test "$str2"\&gt;"$str3"只会检查单个参数是否为空。)

由于您使用的是bash,因此使用[[ 而不是[ 要简单得多。 [[ 不是常规命令;这是bash 识别的特殊语法,因此不适用正常的处理规则。这里最相关的是&gt;是一个字符串比较运算符,而不是一个重定向运算符,所以它不需要转义。

    if [[ $str2 > $str3 ]]

【讨论】:

  • @slevy1 该页面上没有任何内容与我所说的相矛盾。 &gt; 不需要在 [[ ]](( )) 内转义,因为两者都是不受正常解析和评估规则约束的特殊 shell 构造。事实上,该页面明确声明&gt;&lt;在与[一起用作字符串比较运算符时都需要转义。
  • @chepner 谢谢!这回答了我的问题
【解决方案2】:

如果你重写代码如下:

#!/bin/bash

    str1=""
    str2="Sad"
    str3="Happy"

    if [[ "$str2" > "$str3" ]]
        then echo "$str2 is greater than $str3"
    elif [[ "$str2" < "$str3" ]]
        then echo "$str2 is less than $str3"
    fi

那么比较应该正确进行,您可以避免无意中创建文件。额外的一对“[”和“]”将代码带出测试上下文,允许比较并避免创建文件。更多信息here 声明如下:

请注意,“>”需要在 [ ] 构造中进行转义。 ... 请注意,“

原因是在测试上下文中,即在 OP 代码中仅使用一对方括号,“>”和“redirection operators。因此,“>”不是分别表示大于和小于,而是表示将命令的输出定向到文件,而“

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    相关资源
    最近更新 更多