3
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.

  • Possible Duplicate of stackoverflow.com/questions/169511/… – rahul Mar 25 '15 at 17:27
  • 3
    This works with bash. What shell are you using? – roaima Mar 25 '15 at 17:28
  • 1
    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). – steeldriver Mar 25 '15 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 '15 at 17:32
  • To know more about this in Bash you can checkout Bash manual - Brace Expansion. – Franklin Yu May 31 at 16:08
5

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.

  • 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 '15 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 '15 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 '15 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 '15 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 '15 at 22:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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