SC2245 – ShellCheck Wiki

See this page on GitHub


-d only applies to the first expansion of this glob. Use a loop to check any/all.

Problematic code:

if [ -f ksh* ]
  echo "The file exists"

Correct code:

for f in ksh*
  if [ -f "$f" ]
    echo "Found a matching file: $f"


Ksh has the curious behavior of ignoring anything after an unrecognized flag to test/[, which means that file checking operators against globs will effectively apply the operator to the first expansion:

[ -f ksh* ]                              # This
[ -f ksh93u ksh93u.tar ksh93u.tar.gz ]   # Becomes this
[ -f ksh93u ]                            # And is interpreted like this

This is an issue when you have multiple matches for a glob. Instead of checking some or all, it only checks the first result and ignores the rest. To ensure that all results are considered (either to check that any or all results match the operator), use a loop explicitly.

If you really only want to match the first result of the glob expansion as sorted alphabetically in the current locale, you can make this intention explicit:

matches=( ksh* )
if [ -f "${matches[0]}" ]
  echo "The first result is a file"


If you only care that entries exists, use -e. ShellCheck does not warn in this case, since all files resulting from glob expansion necessarily exist.

ShellCheck is a static analysis tool for shell scripts. This page is part of its documentation.