The short of it: for counter-based loops, use the C-like form of the for
loop:
for (( a = 0; a < $1; a++ )); do
# ... use $a
done
(This replaces while [ $a -lt $1 ]; do a='expr $a + 1' ...; done
.)
See below for more on the rules that apply inside (( ... ))
.
As for the rest of your code:
- Conditional
[ "$2" "1"]
is broken: it's missing the mandatory space before ]
- With that fixed, it'll only work if
$2
expands to a unary test operator such as -n
.
- Perhaps you meant
if [[ -z $myrand ]]; then
, to check if $RANDOM
resulted in a nonempty string?
a='expr $a + 1'
- which you don't need anymore with the for
loop - doesn't actually invoke expr
, because you're using single quotes - you'd need backticks (`) instead, or, preferably, the modern equivalent: $(expr $a + 1)
. However, with arithmetic evaluation, this could be simplified to (( ++a ))
.
[ ... ]
conditionals work in bash, but they're provided for POSIX compatibility - use [[ ... ]]
as the bash-specific alternative, which is more robust, has more features, and is faster.
bash statements only need terminating with ;
if you place multiple on a single line
- Note that bash considers
do ...
and then ...
separate statements, hence you often see if ...; then
and for ...; do
.
- In general, I encourage you to syntax-check your shell code at http://shellcheck.net - it's a great tool for detecting syntax problems.
Note how different rules apply inside (( ... ))
compared to elsewhere in bash
:
- spaces around the
=
in the variable assignment are allowed.
- referencing a variable without the
$
prefix (a++
) is allowed.
<
performs numerical comparison (whereas inside [[ ... ]]
it's lexical) -i.e., it's the more natural equivalent to -lt
inside [ ... ]
or [[ ... ]]
.
- several other mathematical and even bit-wise operators are supported
- ...
All these different rules apply when bash operates in an arithmetic context, which applies to (( ... ))
, $(( ... ))
, array subscripts, and other cases.
For all the rules, run man bash
and read the ARITHMETIC EVALUATION
section.