在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"
答案 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脚本只有一个退出点没有特别的优点 - 也没有任何伤害,但致命错误也可能终止脚本。
唯一的争论点是在退出之前是否要尽可能多地诊断问题,或者是否只是诊断第一个问题。平均而言,仅仅诊断第一个就容易多了。