Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 877
dot Avatar asked Apr 04 '14 13:04

dot


People also ask

Can you do for loops in bash?

A bash for loop is a bash programming language statement which allows code to be repeatedly executed. A for loop is classified as an iteration statement i.e. it is the repetition of a process within a bash script. For example, you can run UNIX command or task 5 times or read and process list of files using a for loop.

What does $() mean in bash?

Example of command substitution using $() in Linux: Again, $() is a command substitution which means that it “reassigns the output of a command or even multiple commands; it literally plugs the command output into another context” (Source).

Is loop available in shell script?

In shell scripting, different types of loops are available to perform looping such as for loop, while loop, and until loop. These loops will execute commands iteratively until a condition satisfies and comes out of the loop when the condition is not satisfied.

What is the syntax of for loop in shell script?

The basic syntax of a for loop is: for <variable name> in <a list of items>;do <some command> $<variable name>;done; The variable name will be the variable you specify in the do section and will contain the item in the loop that you're on.


2 Answers

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
like image 139
Josh Jolly Avatar answered Oct 02 '22 00:10

Josh Jolly


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
like image 36
Jessada Thutkawkorapin Avatar answered Oct 02 '22 01:10

Jessada Thutkawkorapin