I run below script:
for (( i=1; i <= 5; i++ ))
do echo "Random number $i: $RANDOM"
doneI am getting below Error:
Syntax error: Bad for loop variablewhy this syntax is not working?
83 Answers
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"
doneOr, 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.shyou are basically running
dash ./script.shAs 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
bashe.g.bash script.sh(you don't need to make the script executable)Make the script executable and from a
bashshell run (from the directory containing the script):./script.shThe most portable way is to use a shebang (
#!/bin/bashor 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 abashscript 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 `
doneThis 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