Assign results of globbing to a variable in Bash Assign results of globbing to a variable in Bash bash bash

Assign results of globbing to a variable in Bash


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.


Consider

for dir in $FOO; do    touch "$dir/rotten_eggs"done

Note that this will touch multiple files if the glob pattern matches more than one pathname.


The code as intended with the result of the glob assigned to the variable would be like this:

$ mkdir ryan$ mkdir ryan/smells-bad$ FOO=(ryan/smells-*)$ echo "${FOO[@]}"ryan/smells-bad$ echo "$FOO"ryan/smells-bad$ touch "$FOO/rotten_eggs"$ ls -l "$FOO"total 0-rw-r--r-- 1 ryan ryan 0 Mar  1 11:17 rotten_eggs

$FOO is actually an array here, but $FOO also works to get the first element of the array.

but, see how the glob can match more than one file (hence the array is a good idea)

$ mkdir ryan/clean$ FOO=(ryan/*)$ echo "$FOO"ryan/clean$ echo "${FOO[@]}"ryan/clean ryan/smells-bad

In these cases the results of the glob is assigned to the variable as desired, rather than the variable being expanded as a glob at point of use.

Of course this means that the variable should really always be used in double quotation marks "..." otherwise if the filename itself (the glob expansion) also had a * in it, it would glob again.

e.g.

$ touch ryan/'*ea*'$ FOO=(ryan/*ea*)$ echo "${FOO[@]}"ryan/clean ryan/*ea*$ echo ${FOO[@]}ryan/clean ryan/clean ryan/*ea*