How to assign a glob expression to a variable in a Bash script?

I think it is the order of expansions:

The order of expansions is: brace expansion, tilde expansion, parameter, variable and arithmetic expansion and command substitution (done in a left-to-right fashion), word splitting, and pathname expansion.

So if your variable is substituted, brace expansion doesn't take place anymore. This works for me:

eval ls $dirs

Be very careful with eval. It will execute the stuff verbatimly. So if dirs contains f{m,k}t*; some_command, some_command will be executed after the ls finished. It will execute the string you give to eval in the current shell. It will pass /content/dev01 /content/dev02 to ls, whether they exist or not. Putting * after the stuff makes it a pathname-expansion, and it will omit non-existing paths:

dirs=/content/{dev01,dev02}*

I'm not 100% sure about this, but it makes sense to me.


Here is an excellent discussion of what you are trying to do.

The short answer is that you want an array:

dirs=(/content/{dev01,dev01})

But what you do with the results can get more complex than what you were aiming for I think.


For folks (like me) finding this through Google, @Peter and @feoh's answers are the general solution to "How to glob variables in bash script".

list_of_results=(pattern)

will save existing filenames matching pattern into the array list_of_results. Each element of list_of_results will hold one filename, spaces and all.

You can access each result as "${list_of_results[<index>]}" for <index> starting from 0. You can get the entire list, properly quoted, as "${list_of_results[@]}".

Tags:

Bash

Glob