bash:如果分支为两个不同的循环

时间:2017-08-28 00:42:14

标签: bash

我正在写一个for循环。但循环取决于位置参数的内容。

  • 如果位置参数为seq 2 1 10,则循环为for i in $(seq 2 1 10)

  • 如果位置参数是纯数字,例如1 2 5 7 10,则循环为for i in 1 2 5 7 10

我尝试了这个,但它不起作用:

test () {
if [[ $1 == seq ]]
then
for i in $(seq $2 $3 $4)
else
for i in $@
fi
do
echo $i
done
}

我也试过这个:

test2 () {
if [[ $1 == seq ]]
then
sss="for i in $(seq $2 $3 $4)"
else
sss="for i in $@"
fi
$sss
do
echo $i
done
}

也行不通。

所以我的问题是:

  1. 我知道我可以在里面写两个明确的循环if。但是如果循环内容很大,这就浪费了代码空间。还有更好的办法吗?
  2. 在我的第二次尝试中,为什么$sss没有扩展到for句子并被bash正确解析?

2 个答案:

答案 0 :(得分:1)

将数字列表保存在数组中。

test () {
    if [[ $1 == seq ]]
    then
        numbers=($(seq "$2" "$3" "$4"))
    else
        numbers=("$@")
    fi

    for i in "${numbers[@]}"
    do
        echo $i
    done
}
  

在我的第二次尝试中,为什么$sss没有扩展到for句子并被bash正确解析?

变量可以扩展为要运行的命令,但不能扩展为流控制构造,如for循环或if语句。那些需要直接写出来,它们不能存储在变量中。如果您尝试,bash将尝试运行名为for的命令 - 也就是说,它会在/bin/usr/bin等中查找名为for的二进制文件

答案 1 :(得分:1)

John Kugelman的答案中使用数组的替代方法是使用set --来更改位置参数:

test () 
{ 
    if [[ $1 == seq ]]; then
        set -- $(seq $2 $3 $4)
    fi
    for i; do
        echo $i
    done
}

请注意,for i相当于for i in "$@"

John已经提到它为什么不起作用 - 在解析控制流之后发生变量插值和分裂。