Test whether a glob has any matches in bash Test whether a glob has any matches in bash bash bash

Test whether a glob has any matches in bash


Bash specific solution:

compgen -G "<glob-pattern>"

Escape the pattern or it'll get pre-expanded into matches.

Exit status is:

  • 1 for no-match,
  • 0 for 'one or more matches'

stdout is a list of files matching the glob.
I think this is the best option in terms of conciseness and minimizing potential side effects.

Example:

if compgen -G "/tmp/someFiles*" > /dev/null; then    echo "Some files exist."fi


The nullglob shell option is indeed a bashism.

To avoid the need for a tedious save and restore of the nullglob state, I'd only set it inside the subshell that expands the glob:

if test -n "$(shopt -s nullglob; echo glob*)"then    echo foundelse    echo not foundfi

For better portability and more flexible globbing, use find:

if test -n "$(find . -maxdepth 1 -name 'glob*' -print -quit)"then    echo foundelse    echo not foundfi

Explicit -print -quit actions are used for find instead of the default implicit -print action so that find will quit as soon as it finds the first file matching the search criteria. Where lots of files match, this should run much faster than echo glob* or ls glob* and it also avoids the possibility of overstuffing the expanded command line (some shells have a 4K length limit).

If find feels like overkill and the number of files likely to match is small, use stat:

if stat -t glob* >/dev/null 2>&1then    echo foundelse    echo not foundfi


#!/usr/bin/env bash# If it is set, then an unmatched glob is swept away entirely -- # replaced with a set of zero words -- # instead of remaining in place as a single word.shopt -s nullglobM=(*px)if [ "${#M[*]}" -ge 1 ]; then    echo "${#M[*]} matches."else    echo "No such files."fi