我正在写一个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
}
也行不通。
所以我的问题是:
$sss
没有扩展到for
句子并被bash正确解析?答案 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已经提到它为什么不起作用 - 在解析控制流之后发生变量插值和分裂。