7
for i in {1..40}
do 
   echo $i
done

I got

{1..40}

and I would like to have something like

1
2
3
and so on

so I can use the variable i inside a command's parameter.

5
  • Possible Duplicate of stackoverflow.com/questions/169511/…
    – rahul
    Mar 25, 2015 at 17:27
  • 3
    This works with bash. What shell are you using? Mar 25, 2015 at 17:28
  • 2
    How exactly are you running the script? it sounds like you may be forcing it to be interpreted by a shell that doesn't support brace expansion e.g. running sh yourscript instead of ./yourscript (where sh may be another shell, such as dash). Mar 25, 2015 at 17:29
  • 1
    I was using #!/bin/sh istead of #!/bin/bash at the beginning of my script.. my bad.. thanks !
    – Benjamin
    Mar 25, 2015 at 17:32
  • To know more about this in Bash you can checkout Bash manual - Brace Expansion. May 31, 2019 at 16:08

1 Answer 1

7

In bash 3.0+ (as well as zsh and ksh93), {1..40} will expand to the numbers from 1-40 (inclusive). In a POSIX shell like dash (which is typical of /bin/sh in e.g. Ubuntu), it will not work (we call this issue a "bashism").

On systems with the GNU utilities, you can use seq to accomplish this:

for i in $(seq 1 40)
do
    echo $i
done

To be more portable, you'll have to manually increment $i in a while loop:

i=1
while [ $i -le 40 ]
do
    echo $i
    i=$((i+1))
done

This portable version is also very slightly faster since it lacks the external command.

11
  • Your while could be i=; until [ "$((i+=1))" -gt 40 ]; do echo "$i". done and, if run in dash is likely faster than anything you would run in bash anyway.
    – mikeserv
    Mar 25, 2015 at 21:57
  • @mikeserv: The $((i+=1)) syntax has been unreliable in my past experiences with older UNIX systems. I don't like until, especially when while will work fine: try i=0; while [ $((i+=1)) -le 40 ]; do echo $i; done
    – Adam Katz
    Mar 25, 2015 at 22:02
  • Ok. The until, while stuff is just style, but what's unreliable about the increment += assign? Basically any of those assignments you can do in C you should be able to do in the shell. |= ^= &= /= *= -= %=. That is, you can do them in a POSIX shell. But you should quote the math expansion in the [ test ] maybe if you don't get explicit about $IFS before hand.
    – mikeserv
    Mar 25, 2015 at 22:06
  • some UNIX systems aren't fully POSIX compliant and miss this particular capability. I'm no longer an admin, and I can't recall which ones, but I've definitely learned not to use assignment inside $(()) notation. Interesting note about quotation, but if $IFS is tampered with, a lot will break; [ is the least of your worries ;-)
    – Adam Katz
    Mar 25, 2015 at 22:08
  • Well, today, it works in ksh93, zsh, mksh, posh, yash, bash, dash... and maybe I'm forgetting one or two. In posh though it won't like v=; : "$((v+=1))" (though it should) but instead prefers v=0; : "$((v+=1))".
    – mikeserv
    Mar 25, 2015 at 22:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .