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

时间:2019-04-11 19:26:04

标签: bash shell

我试图从txt文件中读取一些文件名,将它们传递到shell变量中,并将其用作命令的参数。但我没想到。

files.txt的内容:

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

我试图像这样比较在files.txt中列出的两个文件:

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

但是我遇到了错误:

cmp: missing operand after '-b'

我意识到$ f1和$ f2没有被正确引用。我应该如何修改命令行?

2 个答案:

答案 0 :(得分:1)

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

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

希望可以避免这些错误。当然,您也可以忽略错误,但这可能不是一个好主意。请注意,该代码中不需要cat。您可以按照以下方式重定向标准输入:

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

最后一件事:读取命令会将第一个空格分隔的值放在f1中,将第二个和其余项放在f2中。也就是说,如果输入文件的第二个文件名后面有多余的内容,则将if推入f2中。为避免这种情况,请考虑在读取末尾放置一个虚拟变量,以获取多余的字段(如果存在)。我已经用第三个变量Extra做到了。

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

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

基本上,bash首先会确保$ f1是可读文件,如果是,它将检查$ f2是可读文件,然后才执行cmb命令。

答案 1 :(得分:0)

我知道上一个问题是怎么回事:在files.txt中,文件末尾有一行额外的行,这使得read -r读入空内容。由于其他文件相同,因此cmp不会显示任何输出。但是,当cmp遇到最后一个空的$f1$f2时,将显示错误:

cmp: missing operand after '-b'

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