for loop syntax in shell script [duplicate]
As heemayl's answer points out, your construction is a bashism. The standard way of doing what you want would be:
for i in 1 2 3 4 5
do
echo "Random number $i: $RANDOM"
done
Or, more easily expandably:
for i in $(seq 1 5)
do
echo "Random number $i: $RANDOM"
done
(See man seq
for more detail).
Your original script has a (( i=1; i <= 5; i++ ))
construct in for
loop which is a bashism and hence is not being understood by dash
.
In Ubuntu sh
is a symbolic link to dash
, so when you are running
sh ./script.sh
you are basically running
dash ./script.sh
As i mentioned earlier dash
is not understanding the C-like for
loop construct, it is showing the error.
To run the script using bash
, you can:
Run it as as an argument to
bash
e.g.bash script.sh
(you don't need to make the script executable)-
Make the script executable and from a
bash
shell run (from the directory containing the script):./script.sh
The most portable way is to use a shebang (
#!/bin/bash
or preferably#!/usr/bin/env bash
) as the first line of your script. In this way you can run the script from any shell by./script.sh
, the script will be interpreted as abash
script and hence will be executed accordingly.
Thought I'd contribute to the discussion a little bit.
It's already been mentioned that the syntax used in your script is a bashism and hence isn't portable, even though this is C-like and is well understood by those familiar with java and C. From asking my own question on unix.stackexchange.com , I've also learned that syntax such as for i in $(seq 1 5)
generates a set of numbers first and then iterates , which can be wasteful if you have a very large set.
A better way to simulate C-like behavior, which is portable, is to use while
loop, with a variable that can be incremented. For instance,
#!/bin/sh
number=0
while [ "$number" -lt 10 ]
do
printf "\t%d" "$number"
number=`expr $number + 1 `
done
This works with bash, dash, zsh, ksh, mksh . . . or basically any shell related to bourne shell. In fact, I've a Unix System V book from like 1995, and I've tested their example for bourne shell and it still works. The behaviour is also that of C-like for loop: you have initial condition, testing condition within while [ . . .]
, and update condition at the end.
csh and tcsh have syntax closer to C language, but its not portable to other shells, and they're not recommended to be used in scripting.
Addition:
Concerning portability of $RANDOM, according to this page on ubuntu wiki, with dash random number generation should rely on using /dev/urandom