如何检查Bash中是否存在某些文件?

时间:2009-02-21 03:53:30

标签: bash shell error-handling

bash脚本中,我必须检查是否存在多个文件。

我知道一种尴尬的方法,如下所示,但这意味着我的主程序必须在丑陋的嵌套结构中:

if [ -f $FILE1 ]
then
if [ -f $FILE2 ]
then
  echo OK
  # MAIN PROGRAM HERE
fi
fi

以下版本不起作用:

([ -f $FILE1 ] && [ -f $FILE2 ]) ||  ( echo "NOT FOUND"; exit 1 )
echo OK

打印

NOT FOUND
OK

有没有一种优雅的方法来做到这一点?

更新:查看已接受的答案。另外,在优雅方面我喜欢Jonathan Leffler's answer

arg0=$(basename $0 .sh)
error()
{
    echo "$arg0: $@" 1>&2
    exit 1
}

[ -f $FILE2 ] || error "$FILE2 not found"
[ -f $FILE1 ] || error "$FILE1 not found"

4 个答案:

答案 0 :(得分:10)

怎么样

if [[ ! ( -f $FILE1 && -f $FILE2 ) ]]; then
    echo NOT FOUND
    exit 1
fi

# do stuff
echo OK

有关help [[样式测试可用的选项,请参阅help test[[。另请阅读this faq entry

您的版本不起作用,因为(...)会生成一个新的子shell,其中exit被执行。因此它只影响子shell,但不影响执行脚本。

以下工作方式是在当前shell中执行{...}之间的命令。

我还应该注意,你必须引用两个变量以确保没有不必要的扩展或分词(它们必须作为一个参数传递给[)。

[ -f "$FILE1" ] && [ -f "$FILE2" ] || { echo "NOT FOUND"; exit 1; }

答案 1 :(得分:4)

我认为你在寻找:

if [ -f $FILE1 -a -f $FILE2 ]; then
    echo OK
fi

有关可以放在man test内的内容的详细信息,请参阅[ ]

答案 2 :(得分:4)

您可以列出文件并循环检查:

file_list='file1 file2 wild*'
for file in $file_list; do
    [ -f $file ] || exit
done

do_main_stuff

答案 3 :(得分:1)

我通常使用变体:

arg0=$(basename $0 .sh)
error()
{
    echo "$arg0: $@" 1>&2
    exit 1
}

[ -f $FILE2 ] || error "$FILE2 not found"
[ -f $FILE1 ] || error "$FILE1 not found"

使shell脚本只有一个退出点没有特别的优点 - 也没有任何伤害,但致命错误也可能终止脚本。

唯一的争论点是在退出之前是否要尽可能多地诊断问题,或者是否只是诊断第一个问题。平均而言,仅仅诊断第一个就容易多了。