如何将 "for loop" BASH 中的大括号扩展到位置参数的正确方法?

How is the correct way to exapand braces in a "for loop" BASH to positional parameters?

当我尝试在 BASH

中编写此函数时
function Odds () for i in {1..${#@}..2} ; do echo $i; done

我期待像

这样的输出

1 3 5...

取决于传递给函数的参数数量。

但有效的输出是${#@}扩展后的字符串。

例如

{1..5..2}

我有一些猜想,但是......任何事情......发生了什么事以及如何避免这种情况并获得理想的输出?

试试这个:

function Odds () { for i in {1..${@}..2} ; do echo $i; done }

function Odds () { for i in {1....2} ; do echo $i; done }

问题是大括号扩展参数替换之前完成。因此,大括号展开 不能与变量一起使用。

选项 1:seq

如果您安装了 seq(这在 Linux 上很常见),请尝试:

function Odds () { seq 1 2 "${#@}"; }

seq 1 2 "${#@}" returns 数字以 1 开始,每次递增 2,直到达到 ${#@}

例如:

$ Odds a b c d e
1
3
5

注意: function 符号不是必需的,它限制了兼容性(它不是 POSIX)。 Odds 可以不用它来定义:

Odds () { seq 1 2 "${#@}"; }

选项 2:bash

或者,只需使用 bash,定义:

function Odds () { for ((i=1; i<=${#@}; i=i+2)); do echo "$i"; done; }

这会产生相同的输出:

$ Odds a b c d e
1
3
5

选项 3:POSIX

为获得最广泛的兼容性,请使用符合 POSIX 标准的函数:

Odds() { i=1; while [ "$i" -le "$#" ]; do echo "$i"; i=$((i+2)); done; }