Reputation: 2857
I have a simple script:
is_prime () {
local factors
factors=( $( factor "$1" | cut -d ':' -f 2 ) )
[ ${#factors} -le 1 ]
}
starting () {
for i in $(seq 10 99); do
if is_prime "$i" ; then echo "$i" ; fi
done
}
starting
If I run it with /bin/zsh
, it prints all the primes between 10 and 99, as I would expect. If I run it with /bin/bash
, however, it does the exact opposite: it prints all non-prime values in that range! I understand zsh
s behaviour, but why does bash do what it does? Is the behaviour of test
different in some relevant way?
Upvotes: 3
Views: 111
Reputation: 80931
Apparently in zsh
this ${#factors}
expansion on an array gets you the length of the array. It doesn't do that in bash
. In bash
that gets you the length of the first element of the array.
Compare these outputs:
$ zsh -c 'foo=(a b c); echo $foo'
a b c
$ bash -c 'foo=(a b c); echo $foo'
a
$ zsh -c 'foo=(a b c); echo ${#foo}'
3
$ bash -c 'foo=(a b c); echo ${#foo}'
1
So that's why your script is going wrong for bash
. To get the value you expected there you need to use ${#factors[@]}
(which also works in zsh
).
$ zsh -c 'foo=(a b c); echo ${#foo[@]}'
3
$ bash -c 'foo=(a b c); echo ${#foo[@]}'
3
Upvotes: 3