Buttle Butkus
Buttle Butkus

Reputation: 9456

Expand `*` inside of variable value in bash

Can I create a bash variable with * in the value and then have that * expanded by the shell upon use?

E.g.

sourcefiles=/path/*.phtml*
filesfound=0

for f in $sourcefiles;
do
  echo "Found file named: $f";
  mv $f /other/path/"$f"
  (($filesfound++))
done

This is running as part of a cron job, and I am getting an error in my email saying:

mv: cannot stat `/path/*.phtml*': No such file or directory

So it seems to me that the * is not expanding, perhaps only when it doesn't find any matches...

Upvotes: 0

Views: 63

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295335

Correct: Not expanding is default behavior when there are no matches!

This lets

ls *.txt

return an error akin to

ls: no file '*.txt' found

instead of falling back to its default behavior of listing all files (as it would if given no arguments).


If you want to evaluate to an empty list, use:

shopt -s nullglob

...or just check if any results exist:

for f in $sourcefiles; do
  [[ -e $f ]] || continue
  echo "Found file named: $f";
  mv "$f" /other/path/"$f"
  ((++filesfound))
done

Alternately, consider:

shopt -s nullglob
sourcefiles=( /path/*.phtml* )
filesfound=${#sourcefiles[@]}

# print entire list, with names quoted to make hidden characters &c readable
printf 'Found file named: %q\n' "${sourcefiles[@]}"

# warning: this only works if the list is short enough to fit on one command line
mv -- "${sourcefiles[@]}" /other/path/

Upvotes: 3

Related Questions