Search code examples
bashshellbrace-expansion

How can I do brace expansion on variables?


Consider the following script:

#! /bin/bash -e

echo {foo,bar}
EX={foo,bar}
echo ${EX}

The output of this script is:

foo bar
{foo,bar}

I would like the the echo command to perform brace expansion on ${EX}. Thus, I would like to see an output of

foo bar
foo bar

I want to create a script where the user can supply a path with curly brackets where every expanded version of it is copied.

Something like this:

#! /bin/bash -e

$SOURCES=$1
$TARGET=$2

cp -r ${SOURCES} ${TARGET}

How can I achieve this?


Solution

  • See man bash:

    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.

    As you see, variable expansion happens later than brace expansion.

    Fortunately, you don't need it at all: let the user specify the braced paths, let the shell expand them. You can then just

    mv "$@"
    

    If you need to separate the arguments, use an array and parameter expansion:

    sources=("${@:1:$#-1}")
    target=${@: -1}
    mv "${sources[@]}" "$target"