【问题标题】:Bash: using the result of a diff in a if statementBash:在 if 语句中使用 diff 的结果
【发布时间】:2021-01-08 00:25:18
【问题描述】:

我正在编写一个简单的 Bash 脚本来检测文件夹何时被修改。

它非常接近:

ls -lR $dir > a
ls -lR $dir > b

DIFF=$(diff a b) 
if [ $DIFF -ne 0 ] 
then
    echo "The directory was modified"

不幸的是,if 语句打印错误:[: -ne: unary operator expected

我不确定我的脚本有什么问题,有人可以帮助我吗?

非常感谢!

杰瑞

【问题讨论】:

    标签: bash diff


    【解决方案1】:
    ls -lR $dir > a
    ls -lR $dir > b
    
    DIFF=$(diff a b) 
    if [ "$DIFF" != "" ] 
    then
        echo "The directory was modified"
    fi
    

    【讨论】:

    • 或更简单的如果 [ "$DIFF" ]
    • diff 有退出状态,可以直接测试,无需使用另一个可执行文件'['。
    • 关于比较退出代码和比较命令输出的答案值得解释一下。
    • 与使用cmp 相比,这非常效率低下。 diff 是一种更慢且更昂贵的工具,您只需要在确切了解区别是什么时使用它,而不是是否有区别。
    • @CharlesDuffy - cmp 缺少比较中可能需要的功能。一个例子是在比较中忽略行。
    【解决方案2】:
    if ! diff -q a b &>/dev/null; then
      >&2 echo "different"
    fi
    

    【讨论】:

    • 这是最直接的测试方式。 (注意:您应该在 echo 命令中添加右引号。)
    • diff 也可能会向 stderr 发送消息,例如权限被拒绝错误,具体取决于您的版本
    • 这个答案完美无缺,但我对否定(!)感到困惑,因为差异手册页:“如果输入相同,则退出状态为 0,如果不同,则为 1, 2 如果有麻烦。” 这是否意味着它应该反过来工作? if ! diff.. then echo "same"?
    • @JoshuaGoldberg bash 的if 的操作方式与 C 不同。如果返回值为 0,它会执行条件操作。查看test 命令的手册页 - 如果为真则返回 0,如果为假则返回 1 .
    【解决方案3】:

    您正在寻找 diff 的返回值,而不是您在示例代码中使用的 diff 的输出。

    试试这个:

    diff a b
    if [ $? -ne 0 ]; then
        echo "The directory was modified";
    fi
    

    【讨论】:

    • 如果您使用这种方法,请注意在 'diff' 命令之后立即进行测试。这很重要,因为 $?包含 LAST 命令的返回码。
    【解决方案4】:

    如果您不需要知道更改是什么,cmp 就足够了。 此外,您还可以使用&&|| 提供的语法技巧:

    cmp a b || echo 'The directory was modified'
    

    该指令可以解释为: “要么 a 和 b 相等,要么我回显消息”。

    &&|| 的语义必须小心处理,但这里很直观)。

    为了可读性,我实际上更喜欢把它放在两行:

    cmp a b \
      || echo 'The directory was modified'
    

    【讨论】:

      【解决方案5】:
      DIFF=$(diff -u <(find dir1/ -type f -printf '%P\n' | sort) <(find dir2/ -type f -printf '%P\n' | sort))
      if [ "$DIFF" ]; then
        echo "Directories differ"
        # Do other stuff here
      fi
      

      这使用了我最喜欢的 bashism 之一,&lt;() 进程替换。

      $DIFF 变量包含可打印的差异。如果您想将其展示给最终用户,请务必双引号,例如echo "$DIFF".

      如果您只想告诉用户存在任何差异,可以将 if 缩短为 [ "$(diff ...)" ] &amp;&amp; echo "Difference found"

      注意:我假设最初的问题意味着dir1dir2 更有意义。如果在时间 0 是 dir,然后在时间 1 是 dir,这种方法显然行不通。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-15
        • 2017-03-06
        相关资源
        最近更新 更多