discussion
Using seq
is fine, as Jim Robert suggested. Pax Diablo suggested a bash loop to avoid calling a subprocess, with the additional advantage of being more memory friendly if $END is too large. Zathrus spotted a typical bug in the loop implementation, and also hinted that since i is a text variable, continuous conversions to-and-fro numbers are performed with an associated slow-down.
integer arithmetic
This is an improved version of the bash loop:
typeset -i i END
let END=5 i=1
while ((i<=END)); do
echo $i
…
let i++
done
If the only thing that we want is the echo
, then we could write echo $((i++))
.
ephemient taught me something: bash allows for ((expr;expr;expr))
constructs. Since I've never read the whole man page for bash (like I've done with the ksh man page, and that was a long time ago), I missed that.
So,
typeset -i i END # let's be explicit
for ((i=1;i<=END;++i)); do echo $i; done
seems to be the cleanest way, and possibly the "fastest"; it sure won't be necessary to allocate memory to consume seq
's output, which could be a problem if END is very large.
the initial question
eschercycle noted that the {a..b} bash notation works only with literals; true, accordingly to the bash manual. One can overcome this obstacle with a single (internal) fork()
without an exec()
(as is the case with calling seq
, which being another image requires a fork+exec):
for i in $(eval echo "{1..$END}"); do
Both eval
and echo
are bash builtins, but a fork()
is required for the command substitution (the $(…)
construct).