The best way to expand glob pattern?

Just let it expand inside an array declaration's right side:

list=(../smth*/)          # grab the list
echo "${#list[@]}"        # print array length
echo "${list[@]}"         # print array elements
for file in "${list[@]}"; do echo "$file"; done  # loop over the array


Note that the shell option nullglob needs to be set.
It is not set by default.
It prevents an error in case the glob (or one of multiple globs) does not match any name.

Set it in bash with

shopt -s nullglob

or in zsh with

setopt nullglob

compgen is a Bash built-in that you can pass an escaped(!) pattern to, and it outputs matches, returning true or false based on whether there were any. This is especially useful if you need to pass the glob pattern from a variable/script argument.

glob_pattern='../smth*/*'
while read -r file; do
    # your thing
    echo "read $file"
done < <(compgen -G "$glob_pattern" || true)

adding the || true prevents a false return from compgen causing any problems. This method avoids issues with no matches and does not require changing nullglob options.

Tags:

Bash

Wildcards