Issue with IF condition

Getting syntax error when the condition after -o returns more than one file

if [ -f /usr3/tstsrc/test/anitha/*.done -o -f /usr3/tstsrc/test/anitha/*.zip ]
then
echo "Found"
fi

output:

=>ls -l
total 5
-rw-rw-r--   1 wes      wes            0 Jun 25 04:51 a.done
-rw-rw-r--   1 wes      wes            0 Jun 25 04:51 a.zip
-rw-rw-r--   1 wes      wes            0 Jun 25 04:51 b.zip
-rwxrwxrwx   1 wes      wes          101 Jun 24 06:37 test.sh
<SunOS>/usr3/tstsrc/test/anitha
=>./test.sh
./test.sh: test: syntax error
<SunOS>/usr3/tstsrc/test/anitha
=>

Input Output
2 done files , 2 Zip files Pass
2 done files , 1 Zip files Pass
1 Done file, 2 Zip files Syntax error
1 Done file, 1 Zip files Pass
0 Done file, 1 Zip file Pass
0 Done file, 2 Zip file Syntax error

if [[ -f /usr3/tstsrc/test/anitha/*.done -o -f /usr3/tstsrc/test/anitha/*.zip ]]
then
echo "Found"
fi

Use the shell's logical OR instead:

~/tmp$ ls *.done *.zip
a.done  a.zip  b.zip
~/tmp$ cat x.sh
if [ -f *.done ] || [ -f *.zip ]
then
echo "Found"
fi
~/tmp$ ./x.sh
Found

EDIT: Also, see this for some other examples of why not to use -o (or -a) with [/test.

No it is not working.

That's not a useful response for anyone trying to help you.

How is it not working? It doesn't produce the expected output? You get an error? Your computer explodes?

Post the output.

@Carlo the my response was for @Srini's input. Im yetto chk out your solution.. will get back in few mins.. Thx for the response..!

I assumed it was, given the times - that doesn't change the fact it tells us nothing useful...

if [[ -f /usr3/tstsrc/test/anitha/*.done || -f /usr3/tstsrc/test/anitha/*.zip ]]
then
echo "Found"
fi

Anytime a filename pattern expansion yields two or more pathnames, tests like:

[ -f pattern ]

will yield a syntax error or (due to the names and number of files involved) unexpected, unreliable test results. You will only get valid results if pattern expands to a single word. NEVER use an * in a pattern in a test like this.

Instead try something like:

for i in /usr3/tstsrc/test/anitha/*.done /usr3/tstsrc/test/anitha/*.zip
do      if [ -f "$i" ]
        then    echo "Found"
                break
        fi
done

How about

 [ 0 -lt $(wc -w < <(ls *.done *.zip)) ] && echo found || echo NOK

(requires recent bash / ksh)

EDIT: or

[ $(ls *.done *.zip 2>/dev/null) ] && echo found || echo NOK

The last one won't work. The ls utility will return a non-zero exit status if any file operand names a file that does not exist. And, you don't need command substitution here. Perhaps you meant something like:

(ls *.done 2>&1 > /dev/null || ls *.zip 2>&1 >/dev/null) && echo Found || echo NONE

The first one also needs to redirect stderr to /dev/null from the ls to avoid unwanted diagnostic output.

Hmm - works for me with bash. It's testing for the non-zero string the ls command substitution gives back and reacts correctly. If there's two non-existing and one existing pattern, it echoes "found". If none of the patterns exists, it echoes "NOK" - I can't say if due to the zero string or due to the exit code.

Hi RudiC,
If I don't have any files matching *.done and 2 files matching *.zip ( a.zip and b.zip ), I get:

-ksh: [: argument expected
NOK

with the ksh , and:

bash: [: a.zip: unary operator expected
NOK

with bash .
I believe the desired result was:

Found
1 Like

You are right, I was not testing thoroughly. Try like

 [ "$(ls *.done *.zip 2>/dev/null)" ] && echo found || echo NONE
1 Like