5

I have the following lines of bash script to test whether a file exists:

MYAPPPATH=$(find $APPDIR -iname myapp* -print)
if [ -e $MYAPPPATH ]
then
    echo "File exists" 
fi

However when file starting with "myapp" does not exist, therefore MYAPPPATH='', the above check succeeds again. See what happens when using set -x and the file does not exist:

++ find /path/to/app -iname 'myapp*' -print
+ MYAPPPATH=
+ '[' -e ']'
+ echo 'File exists'

What is the reason for this?

What do I need to do in order to make this work as expected?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
trikelef
  • 381
  • 1
  • 4
  • 13

3 Answers3

13

When your variable is empty, your command becomes:

[ -e ]

In this case, you call [..] with one argument -e. String "-e" is not null, so test return true.

This behavior is defined by POSIX test:

In the following list, $1, $2, $3, and $4 represent the arguments presented to test:

0 arguments:

Exit false (1).

1 argument:

Exit true (0) if $1 is not null; otherwise, exit false.

....

To make it works, you must double quote your variable:

[ -e "$MYAPPPATH" ]

This works because -e with an argument that is an empty string is false.

cuonglm
  • 150,973
  • 38
  • 327
  • 406
5

Get used to quoting variables. Always quote them; that prevents misassessments when it is necessary:

if [ -e "$MYAPPPATH" ]

This would not have happened with the bash-specific compound command:

if [[ -e $MYAPPPATH ]]
Hauke Laging
  • 88,146
  • 18
  • 125
  • 174
  • 4
    Strictly speaking, `[[...]]` was copied by `bash` from `ksh`. It's also supported by `zsh`. So it's not bash-specific (though it's not standard/POSIX sh syntax so should not be used in `sh` scripts). – Stéphane Chazelas Nov 20 '14 at 11:34
2

There are some other ways:

  1. Check variable before (with editions according to comments)

    if [ -n "$MYAPPPATH" ] && [ -e "$MYAPPPATH" ] ; then ...
    
  2. Use locate* instead of find

    if locate -w "$APPDIR/myapp*" ; then ...
    

*1 To use locate don't forget to update files database by updatedb

terdon
  • 234,489
  • 66
  • 447
  • 667
Costas
  • 14,806
  • 20
  • 36
  • `-n "$MYAPPPATH"` is easier to understand. – Hauke Laging Nov 20 '14 at 11:32
  • `-a/-o` should be avoided. Here, probably `$MYAPPPATH` starts with `./` or `/`, so it shouldn't be a problem, but that code above fails to work properly with some shells (like `bash`) with `MYAPPPATH='!'` or `MYAPPPATH='('` or `MYAPPPATH='-e'`... use `if [ -n "$MYAPPPATH" ] && [ -e "$MYAPPPATH" ]; then...` – Stéphane Chazelas Nov 20 '14 at 11:33