3
$ set a b c
$ echo $1 $2 $3
a b c
$ echo ${1..3}
-bash: ${1..3}: bad substitution

I want to echo $1 $2 $3 with brace expansion. But it doesn't work.

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.

According to the bash manual, brace expansion is performed before parameter expansion.

So I think bash should perform brace expansion on ${1..3} first, convert it to echo $1 $2 $3, and then perform parameter expansion.

However, the fact is that bash complains ${1..3} is a bad substitution. Why is that?

PS: Thank you guys!All you answers are wonderful.But I think

Ignacio Vazquez-Abrams's answer is closer to what I want.

Huihoo
  • 133
  • 6

2 Answers2

6

It thinks that the braces are part of the parameter substitution since it follows a dollar sign, and "$1..3" is an invalid variable name.

Try "${@:1:3}" instead.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
3

Ignacio's answer is the right way to do, but here's a bit more detail about how to make it work the way you started it.

You'd have liked ${1..3} to expand to $1 $2 $3. We can't concatenate $ and {1..3} and have it work, or bash will interpret it as a parameter expansion (and fail). To have it interpreted as brace expansion, neutralize the dollar sign by escaping it:

user$ echo \${1..3}
$1 $2 $3

As you noticed, it outputs dollar-expressions without evaluating them. That's because quote removal (the part that converts \$ back to $) is performed after parameter expansion. So we'd need to run it back through eval:

user$ eval echo \${1..3}
a b c

More complex than needed when it could be written as echo "$@"

Community
  • 1
  • 1
JB.
  • 40,344
  • 12
  • 79
  • 106