Assign results of globbing to a variable in Bash

Rob Fisher picture Rob Fisher · Feb 10, 2012 · Viewed 9.6k times · Source

My colleague, Ryan, came to me with a bug in his Bash script, and I identified the problem with this test:

$ mkdir ryan
$ mkdir ryan/smells-bad
$ FOO=ryan/smells-*
$ echo $FOO
ryan/smells-bad
$ touch $FOO/rotten_eggs
touch: cannot touch `ryan/smells-*/rotten_eggs': No such file or directory

From this I infer that the globbing happens during the echo command, not when the variable FOO is created.

We have a couple of workarounds, in descending order of ungracefulness:

touch `echo $FOO`/rotten_eggs

Or:

pushd
cd $FOO
touch rotten_eggs
popd

But neither is satisfying. Am I missing a trick?

Answer

jordanm picture jordanm · Feb 10, 2012

The problem is that the glob will only expand if the file "rotten_eggs" exists, because it is included in the glob pattern. You should use an array.

FOO=( ryan/smells-* )
touch "${FOO[@]/%//rotten_eggs}"

The FOO array contains everything matched by the glob. The expansion using % appends /rotten_eggs to each element.