dot
dot

Reputation: 15700

bash script - can't get for loop working

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.

Upvotes: 12

Views: 14181

Answers (4)

Josh Jolly
Josh Jolly

Reputation: 11796

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

Upvotes: 12

Jessada Thutkawkorapin
Jessada Thutkawkorapin

Reputation: 1346

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

Upvotes: 3

Stephan Kulla
Stephan Kulla

Reputation: 5077

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.

Upvotes: 0

cheezsteak
cheezsteak

Reputation: 2921

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

Upvotes: 0

Related Questions