12

Background Info:

I'm trying to follow the example posted here: http://www.cyberciti.biz/faq/bash-for-loop/ I would like loop 9 times using a control variable called "i".

Problem Description

My code looks like this:

for i in {0..8..1}
do
  echo "i is $i"
  tmpdate=$(date -d "$i days" "+%b %d")
  echo $tmpdate
done

When I run this code, the debug prints show me:

                 "i is {0..8..1}" 

instead of being a value between 0 and 8.

What I've Checked So Far:

I've tried to check my version of bash to make sure it supports this type of syntax. I'm running version 4,2,25(1)

I also tried using C like syntax where you do for (i=0;i<=8;i++) but that doesn't work either.

Any suggestions would be appreciated.

Thanks.

EDIT 1

I've also tried the following code:

for i in {0..8};
do
  echo "i is $i"
  tmpdate=$(date -d "$i days" "+%b %d")
  echo $tmpdate
done

And...

for i in {0..8}
do
  echo "i is $i"
  tmpdate=$(date -d "$i days" "+%b %d")
  echo $tmpdate
done

They all fail with the same results.

I also tried:

#!/bin/bash

for ((i=0;i<9;i++));
do
  echo "i is $i"
  tmpdate=$(date -d "$i days" "+%b %d")
  echo $tmpdate
done

And that gives me the error:

test.sh: 4: test.sh: Syntax error: Bad for loop variable

FYI. I'm running on ubuntu 12

EDIT 2

Ok... so i think Weberick tipped me off to the issue... To execute the script, I was running "sh test.sh" when in the code I had defined it as a BASH script! My bad!

But here's the thing. Ultimately, I need it to work in both bash and sh. so now that I'm being careful to make sure that I invoke the script the right way... I've noticed the following results:

  1. when defined as a bash script and i execute using bash, the C-style version works!
  2. when defined as an sh script and i execute using sh, the C-style version fails

    me@devbox:~/tmp/test$ sh test.sh test.sh: 5: test.sh: Syntax error: Bad for loop variable

  3. when defined as an sh script and i execute using sh the NON c style version ( aka for i in {n ..x}), I get the "i is {0..8}" output.

PS. The ";" doesn't make a difference if you have the do on the next line...just FYI.

7
  • Your example works for me... Commented Apr 4, 2014 at 13:13
  • also I think you need a ; like for i in {0..8}; Commented Apr 4, 2014 at 13:13
  • 2
    how do you run the script? did you use 'bash myscript.sh' or added '#!/bin/bash'? Commented Apr 4, 2014 at 13:16
  • 3
    Also curious as to how the script is being run (ie are you doing sh myscript.sh or ./myscript.sh? - Ubuntu's default shell is dash, which won't recognise some of this syntax) Commented Apr 4, 2014 at 13:27
  • 1
    thats what i suspected, you are not actually running bash at all. ubuntu probably created a link from /bin/bash to dash. Commented Apr 4, 2014 at 13:31

4 Answers 4

12

Ubuntu's default shell is dash, which doesn't recognise either of the bashisms (brace expansion, C-style for loop) you tried. Try running your script using bash explicitly:

bash myscript.sh

or by setting the shebang to #!/bin/bash. Make sure NOT to run the script with sh myscript.sh.

dash should work if you use seq:

for i in $(seq 0 1 8); do
    echo "$i"
done

Just {0..8} should work in bash, the default increment is 1. If you want to use a C-style for loop in bash:

for ((i=0;i<9;i++)); do 
    echo "$i"
done
Sign up to request clarification or add additional context in comments.

2 Comments

this is what i was looking for! it works both ways using seq. invoking via "bash test.sh" or "sh test.sh". thanks.
6 years late but this just helped me out, thanks a lot :)
3

I'm confident that

#!/bin/bash

for ((i=0;i<9;i++))
do
  echo "i is $i"
  tmpdate=$(date -d "$i days" "+%b %d")
  echo $tmpdate
done

work on Ubuntu 12.04

If you still have an error, can you please try running

chmod +x test.sh

then

./test.sh

And the result is

i is 0
Apr 04
i is 1
Apr 05
i is 2
Apr 06
i is 3
Apr 07
i is 4
Apr 08
i is 5
Apr 09
i is 6
Apr 10
i is 7
Apr 11
i is 8
Apr 12

Comments

0

I'm no expert at bash but according to tdlp you need a ; after the for statement. There are many ways to to a range. This is one of them.

    #!/bin/bash
    for i in `seq 1 8`; do
        echo $i
    done

Comments

0

The site you quote says

Bash v4.0+ has inbuilt support for setting up a step value using {START..END..INCREMENT} syntax:

So you can just use {0..8..1} when you have a bash version greater than 4.0, which I guess is not the case (try bash --version in your terminal). Instead of {0..8..1} you can also use {0..8}.

If you have an older version you can use instead of {START..END..INCREMENT} the command $(seq START INCREMENT END) in the for loop.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.