首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么diff命令不能像我在这个Bash脚本中期望的那样工作呢?

为什么diff命令不能像我在这个Bash脚本中期望的那样工作呢?
EN

Ask Ubuntu用户
提问于 2022-10-25 08:24:11
回答 2查看 301关注 0票数 2

我不明白为什么diff命令在我的脚本中不能正常工作。有人能帮我澄清一下吗?

下面是bash脚本:

代码语言:javascript
复制
#!/bin/bash

SRC="src-folder"
DST="dst-folder"
FILES=( a/ b/ c/ )

for f in ${FILES[@]}; do
  cmd="diff -q  $SRC/$f $DST/$f"
  echo $cmd  # row-9
  $cmd       # row-10
done

脚本输出看起来如下所示:

代码语言:javascript
复制
diff -q src-folder/a/ dst-folder/a/
diff -q src-folder/a/ dst-folder/a/
diff -q src-folder/a/ dst-folder/a/
diff -q src-folder/a/ dst-folder/a/
diff -q src-folder/a/ dst-folder/a/
diff -q src-folder/a/ dst-folder/a/
diff -q src-folder/a/ dst-folder/a/
(until buffer overflow)

当我禁用/删除/注释行-10时,我可以看到正确的输出(当我在交互式shell中运行这些命令时,而不是在脚本中,我得到了正确的结果):

代码语言:javascript
复制
diff -q src-folder/a/ dst-folder/a/
diff -q src-folder/b/ dst-folder/b/
diff -q src-folder/c/ dst-folder/c/

当我将diff更改为rsync时,一切都正常工作(从脚本调用)。

那么,如何在脚本中使用diff呢?我的脚本调用的diff没有按预期工作的原因是什么?

我还尝试了一个非常简单的脚本:

代码语言:javascript
复制
#!/bin/bash

diff -q  src-folder/a dst-folder/a
diff -q  src-folder/b dst-folder/b

但不起作用。当我将diff命令更改为任何其他命令(例如rsync)时,一切都正常。

EN

回答 2

Ask Ubuntu用户

发布于 2022-10-25 10:58:06

医生:为我工作。

很长的答案:当我在我的一台测试机器上运行来自您的问题的脚本时,它的行为与预期完全相同:

代码语言:javascript
复制
a-schmidt@s-laugz2repo01:~$ ./show-diffs
diff -q src-folder/a/ dst-folder/a/
diff: src-folder/a/: No such file or directory
diff: dst-folder/a/: No such file or directory
diff -q src-folder/b/ dst-folder/b/
diff: src-folder/b/: No such file or directory
diff: dst-folder/b/: No such file or directory
diff -q src-folder/c/ dst-folder/c/
diff: src-folder/c/: No such file or directory
diff: dst-folder/c/: No such file or directory
a-schmidt@s-laugz2repo01:~$

因此,很明显,您系统上的diff命令与我的不一样。有几种可能会发生这种情况,例如,通过shell别名或在本地安装该名称的程序。为了找出它是什么,输入shell命令:

代码语言:javascript
复制
type diff

在未经修改的Ubuntu系统上,这将输出:

代码语言:javascript
复制
diff is /usr/bin/diff

如果它输出其他东西,如"diff被别名为.“或者"diff是一个函数.“然后,您需要查看您的shell配置文件,以找出更改的位置,并可能对其进行更正。

票数 1
EN

Ask Ubuntu用户

发布于 2022-10-26 10:01:04

我认为问题在于,在命令cmd="diff -q $SRC/$f $DST/$f"中有一些选项,在第10行展开之后,$cmd中包含的字符串不会被正确地计算为Bash的命令。

当您使用exec命令时,$cmd中包含的字符串将被正确计算。但是exec所做的是将当前的shell替换为执行命令的新shell,这样在第一次迭代之后循环就不再存在了。

我已经高亮显示了几次求值,因为在Bash中有eval命令,它正是这样做的-将字符串计算为命令。因此,我认为正确的解决方案是像这样修改脚本:

代码语言:javascript
复制
eval $cmd       # row-10

最后要注意的是,如果是整个脚本,为什么需要将命令赋值给一个立即(在下一行)求值的变量?我的意思是,在这种特殊情况下,您可以简化循环,如下所示:

代码语言:javascript
复制
for f in ${FILES[@]}; do
  diff -q  "$SRC/$f" "$DST/$f"
done
票数 1
EN
页面原文内容由Ask Ubuntu提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://askubuntu.com/questions/1437216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档