外壳变量不能用作另一个外壳命令的参数



我尝试从txt文件中读取一些文件名,将它们传递到shell变量中,并将它们用作命令的参数。但无法得到我的期望。

文件内容.txt:

directory1/to/foo1 directory2/to/foo1
directory1/to/foo2 director2/to/foo2
...

我试图比较文件中列出的两个文件.txt如下所示:

cat files.txt | while read -r f1 f2; do cmp -b $f1 $f2; done

但我得到错误:

cmp: missing operand after '-b'

我意识到 $f 1 和 $f 2 没有得到正确引用。我应该如何修改我的命令行?

您可以通过以下一些预检查来保护 cmp 免受无效文件名的影响:

cat files.txt | while read -r f1 f2 extra; do  [ -r "$f1" ] && [ -r "$f2" ] && cmp -b "$f1" "$f2"; done

这应该有望避免错误。 当然,您也可以忽略错误,但这可能不是一个好主意。 请注意,此代码中不需要 cat。 您可以按如下方式重定向 stdin:

while read -r f1 f2 extra; do  [ -r "$f1" ] && [ -r "$f2" ] && cmp -b "$f1" "$f2"; done <files.txt

最后一件事:read 命令会将第一个空格分隔的值放在 f1 中,将第二个和剩余的项目放在 f2 中。 也就是说,如果输入文件在第二个文件名之后有额外的内容,if 将被推入 f2。 为避免这种情况,请考虑在读取结束时放置一个虚拟变量,以获取无关字段(如果存在)。 我已经用第三个变量完成了这个,额外的。

我添加到 cmp 命令的其他语法是这样的:

[ -r "$f1" ] && [ -r "$f2" ] && cmp -b "$f1" "$f2"

本质上,bash 将首先确保 $f 1 是可读文件,如果是,它将检查 $f 2 是否是可读文件,然后才会继续执行 cmb 命令。

我知道我之前的问题发生了什么:files.txt我在文件末尾有一行额外的行,这使得read -r读取内容为空。由于其他文件相同,因此cmp未显示任何输出。但是当cmp遇到最后一个空$f1$f2时,会显示一个错误:

cmp: missing operand after '-b'

谢谢你们的上述所有答案。非常感谢他们!

最新更新