如何测试两个文件是否存在?

43

我想检查两个文件是否都存在,但是我得到了

test.sh: line 3: [: missing `]'

有人能看出问题在哪里吗?

#!/bin/sh

if [ -f .ssh/id_rsa && -f .ssh/id_rsa.pub ]; then
   echo "both exist"
else
   echo "one or more is missing"
fi

2
如果你使用'test'代替'[',问题就更加明显了。"if test -f .ssh/id_rsa && test -f .ssh/ir_rsa.pub; then"可以正常工作。 - William Pursell
4个回答

61
尝试添加一个额外的方括号。
if [[ -f .ssh/id_rsa && -f .ssh/id_rsa.pub ]]; then

4
具体是 [[(无空格)而不是 [ [(有空格)。不知为何,当我看到这个答案时,我认为有空格也可以,但事实并非如此! - gusterlover6

37
[ -f .ssh/id_rsa -a -f .ssh/id_rsa.pub ] && echo both || echo not
或者
[[ -f .ssh/id_rsa && -f .ssh/id_rsa.pub ]] && echo both || echo not

如果您采用[[ ]]的解决方案,建议您将#!/bin/sh更改为#!/bin/bash,以符合您问题的标签要求。


1
[[ ]] 也被 kshzsh 和可能其他 shell 支持。但最好使用 #!/bin/bash 而不是 #!/bin/sh - oHo
@oHessling,是的,我只是试图将我的答案限制在问题中列出的shell集合中 - 一个在标签中,另一个在shebang行中。 - Michael Krelin - hacker
是的,你的回答非常完美(简短而正确)。只是缺少一个注释来指出一些Shell兼容性问题。但是这个细节不必在你的答案中提到,只需要在下面加上一个小注释即可;-) 祝好! - oHo
@oHessling,不是要声称完美无缺,但最后一句话提到附带bashisms和相应的shebang行是我试图覆盖一些shell兼容性的尝试。当然,将其扩展到其他shell绝对不会损害答案,并且是一个有用的注释。 - Michael Krelin - hacker

17

[[ 是Bash特定的语法。对于兼容POSIX的Shell,您需要使用:

[ -f file1 ] && [ -f file2 ]

7
if [ -e .ssh/id_rsa -a -e .ssh/id_rsa.pub ]; then
 echo "both exist"
else
 echo "one or more is missing"
fi

在这里,

-e 仅检查文件是否存在。如果存在,则返回 true。否则,返回 false。

-f 也是同样的操作,但它会检查给定的文件是否是普通文件。基于此,它会返回 true/false。

然后您使用 &&。因此,需要两个 [[..]] 括号来执行。

相反,您可以使用 -a [与 && 操作符相同] -o [与 || 操作符相同]。

如果您需要更多信息,请查阅以下链接:

http://linux.die.net/man/1/bash.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接