Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

For example, I want to put some file names inside braces for expansion like this:

$ ls
blue_texture  blue_waves  green_light
$ ls -m | tr -d ' \n'
$ echo foo/bar/{`ls -m | tr -d ' \n'`}

My question why doesn't brace expansion work here? I expected it to work as following:

$ echo foo/bar/{blue_texture,blue_waves,green_light}
foo/bar/blue_texture foo/bar/blue_waves foo/bar/green_light
share|improve this question
up vote 7 down vote accepted

The reason this does not work is because bash performs brace expansion before command substitution (the Bash Reference Manual has some information about this). The substitution is not performed until after the brace expansion already occurred.

The only way you could do this is by using eval, but do not do that in this case, as you will allow arbitrary command execution.

Instead you have to seek some other method. This should produce the output you seek:

for file in *; do
    printf '%s ' "foo/bar/$file"
done; echo
share|improve this answer

With zsh:

echo foo/bar/$^l

(${^array} turns on brace-expansion style expansion for the array).


echo ./*(:s:.:foo/bar:)

Applies a history-expansion style substitution to filename expansion.

With any shell

printf 'foo/bar/%s\n' *


set -- *
for i do
  set -- "$@" "foo/bar/$i"
echo "$@"

(note that echo in most shells performs some transformations on the arguments it gets so is better avoided for arbitrary input).

share|improve this answer
+1 that is a very cool use of set/shift – glenn jackman Nov 15 '12 at 21:38

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.