2009-02-21 3 views
6

В сценарии bash я должен проверить наличие нескольких файлов.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: [email protected]" 1>&2 
    exit 1 
} 

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

ответ

10

Как насчет

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

# do stuff 
echo OK 

См help [[ и help test для вариантов используемых с тестами [[ стиля. Также читайте this faq entry.

Ваша версия не работает, потому что (...) порождает новую подкоманду, в которой выполняется exit. Это значит, что это влияет только на подоболочку, но не на исполняемый скрипт.

Вместо этого выполняется выполнение команд между {...} в текущей оболочке.

Следует также обратить внимание на то, что вы должны указывать обе переменные, чтобы не было никакого нежелательного расширения или разбиения слов (они должны быть переданы как один аргумент [).

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

Спасибо, что хорошо выглядит. Просто «или» (||) должно быть «и» (&&), я думаю. – Frank

+0

исправлено уже :) сложно с логикой вечером :) –

4

Я думаю, что вы ищете:

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

См man test для более подробной информации относительно того, что вы можете поместить внутрь [ ].

+0

+1 для 'man test'. Благодаря! – binarybob

3

Вы можете получить список файлов и проверить их в цикле:

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

do_main_stuff 
1

я обычно использую вариант на:

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

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

Там нет особой добродетели в создании сценария оболочки имеет один выход точка - тоже не вред, но фатальные ошибки могут также прекратить выполнение сценария.

Единственный спорный вопрос заключается в том, следует ли диагностировать как можно больше проблем до выхода, или просто диагностировать первое. В среднем диагностировать только первое намного проще.

Смежные вопросы