Bash check shows file exists for non-existent files?

You probably need to surround $stuff in quotes

if [ -f "$stuff" ]; then

As a general rule, you almost always want to add quotes around pathnames everywhere you use them.

I find it more useful to think or variables in shell scripting as “macros”, which are expanded on first use to their value. This is different from variables in almost every other programming language.

So if $stuff contains hello world (notice the space), it would be the same as if you’ve typed:

[ -f hello world ]

which is obviously an error.

In this case, you mentioned that you’re dealing with a non-existent file, so $stuff is actually empty, which would be like typing:

[ -f ]

Which is actually valid, but always succeeds. This is a bit of obscure test behaviour, from the POSIX spec we read that test always succeeds if there if only a single argument (in this case, the argument is -f):

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

This is probably to facilitate the writing of:

[ $variable_that_may_or_may_not_be_defined ]

If you add quotes, you’re passing 2 arguments, and more sane things happen:

if [ -f "" ]; then

Leave a Comment