`if [[ -f *.png ]]` always returns false

In this example, I have a directory of 2 PNG files:

% ls test_folder
1.png 2.png

Listing all PNG files within the directory works:

% echo test_folder/*.png
test_folder/1.png test_folder/2.png

However, checking if a directory contains any PNG file always returns false.

% if [[ -f test_folder/*.png ]]; then echo 'found'; else echo 'not found'; fi
not found

I’ve been told by this guide that this would work. Where did I go wrong? And please excuse my limited understanding of Bash.

>Solution :

Explained in bash manual:

[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of
the conditional expression expression. Expressions are
composed of the primaries described below under
CONDITIONAL EXPRESSIONS. Word splitting and pathname
expansion are not performed on the words between the [[
and ]]
; tilde expansion, parameter and variable expansion,
arithmetic expansion, command substitution, process
substitution, and quote removal are performed.
Conditional operators such as -f must be unquoted to be
recognized as primaries.

Instead you could use an array and check the count:

shopt -s nullglob #  prevents non-matching glob expanding to itself
                  #  can enable later if you prefer to keep that behaviour

pngs=(test_folder/*.png)

if [[ ${#pngs[@]} -gt 0 ]] ; then echo 'found'; else echo 'not found'; fi

Leave a Reply