In a bash
script, I have to check for the existence of several files.
I know an awkward way to do it, which is as follows, but that would mean that my main program has to be within that ugly nested structure:
if [ -f $FILE1 ]
then
if [ -f $FILE2 ]
then
echo OK
# MAIN PROGRAM HERE
fi
fi
The following version does not work:
([ -f $FILE1 ] && [ -f $FILE2 ]) || ( echo "NOT FOUND"; exit 1 )
echo OK
It prints
NOT FOUND
OK
Is there an elegant way to do this right?
UPDATE: See the accepted answer. In addition, in terms of elegance I like 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"
How about
if [[ ! ( -f $FILE1 && -f $FILE2 ) ]]; then
echo NOT FOUND
exit 1
fi
# do stuff
echo OK
See help [[
and help test
for the options usable with the [[
style tests. Also read this faq entry.
Your version does not work because (...)
spawns a new sub-shell, in which the exit
is executed. It therefor only affects that subshell, but not the executing script.
The following works instead, executing the commands between {...}
in the current shell.
I should also note that you have to quote both variables to ensure there is no unwanted expansion or word splitting made (they have to be passed as one argument to [
).
[ -f "$FILE1" ] && [ -f "$FILE2" ] || { echo "NOT FOUND"; exit 1; }
I think you're looking for:
if [ -f $FILE1 -a -f $FILE2 ]; then
echo OK
fi
See man test
for more details on what you can put inside the [ ]
.
You can list the files and check them in a loop:
file_list='file1 file2 wild*'
for file in $file_list; do
[ -f $file ] || exit
done
do_main_stuff
I usually use a variant on:
arg0=$(basename $0 .sh)
error()
{
echo "$arg0: $@" 1>&2
exit 1
}
[ -f $FILE2 ] || error "$FILE2 not found"
[ -f $FILE1 ] || error "$FILE1 not found"
There's no particular virtue in making the shell script have a single exit point - no harm either, but fatal errors may as well terminate the script.
The only point of debate would be whether to diagnose as many problems as possible before exiting, or whether to just diagnose the first. On average, diagnosing just the first is a whole lot easier.