What is the difference between these two things? What is the difference between these two things? bash bash

What is the difference between these two things?


Why the first expression does not work as expected

  1. Brace expansion is executed before variable expansion. $number1..$number2 is not a valid sequence expression, so the whole expression is left unchanged.
  2. After that, variable expansion takes place, resulting in the expression {1..3} (given that number1=1 and number2=3).

Why the second expression does

Your second example works the same, except that the result of variable expansion ({1..3}) is passed to Bash again via eval, giving brace expansion a second chance: 1..3 is a correctly formed sequence expression and therefore brace expansion yields the expected result:

1 2 3

Avoid using eval

Using eval should generally be avoided, as it easily introduces security problems: If number1 or number2 receive input and are not properly sanitized, malicious code can be injected into your program. See this related question for ways to replace eval in various use cases.

In your specific example, the sequence could instead be created by a for loop combined with arithmetic evaluation:

for ((i=number1 ; i<=number2; i+=1)); do echo -n "$i" ; done | xargs1 2 3

A popular non-Bash solution would be to use seq (as pointed out by Walter A in his answer) as in seq "$number1" "$number2" | xargs.

Note: xargs joins multi-line output to a single line in these examples.

Further information

This answer to a related question gives more information on the topic.

Also, the EXPANSION section in the bash(1) manual page is pretty informative on sequence and workings of different expansion mechanisms.


The substitution of the variables is to late.
You can avoid eval with

seq -s " " "$number1" "$number2"