When I try write this function in BASH
function Odds () for i in {1..${#@}..2} ; do echo $i; done
I expected for an output like
1 3 5...
depending on number of arguments passed to the function.
But the efective output is the string with ${#@} expanded.
Ex
{1..5..2}
I have some conjectures but... any away... what is happing and how to avoid this and get the desirable output?
The problem is that brace expansion is done before parameter substitution. Consequently, brace expansion can't be used with variables.
If you have seq
installed (this is common on Linux), try:
function Odds () { seq 1 2 "${#@}"; }
seq 1 2 "${#@}"
returns numbers starting with 1
and incremented by 2
each time until ${#@}
is reached.
For example:
$ Odds a b c d e
1
3
5
Note: The function
notation isn't necessary and limits compatibility (it's not POSIX). Odds
can be defined without it:
Odds () { seq 1 2 "${#@}"; }
Alternatively, just using bash, define:
function Odds () { for ((i=1; i<=${#@}; i=i+2)); do echo "$i"; done; }
This produces the same output:
$ Odds a b c d e
1
3
5
For widest compatibility, use a function that meets the POSIX standard:
Odds() { i=1; while [ "$i" -le "$#" ]; do echo "$i"; i=$((i+2)); done; }