在 POSIX sh 中迭代时修改位置参数
Modifying positional parameters while iterating over them in POSIX sh
这是便携式的吗?
filter() {
set -- CUT "$@"
for x; do
if test "$x" = CUT; then
set -- # ignore args upto here
else # perhaps more filtering
set -- "$@" "$x"
fi
done
printf "'%s' " "$@"; echo
}
filter "$@"
即我可以在迭代时更改 "$@"
吗? for
复合是否重复隐式数组?
filter 1 2 CUT 3
似乎适用于 dash
、ash
、busybox sh
。
是的,POSIX 确实允许这样做。从标题为 The for Loop 的部分可以推断出(在下面引用,重点是我的)循环保留了它自己要迭代的项目列表的私有副本,并且对 shell 所做的更改执行循环时的执行环境不会对所述副本产生任何影响。
for name [ in [word ... ]]
do
compound-list
done
First, the list of words following in
shall be expanded to generate a list of items. Then, the variable name
shall be set to each item, in turn, and the compound-list
executed each time.
Omitting:
in word...
shall be equivalent to:
in "$@"
换句话说,可以保证程序中的循环遍历位置参数的初始列表,因为 "$@"
的隐含扩展先于 set --
和 set -- "$@" "$x"
。
这是便携式的吗?
filter() {
set -- CUT "$@"
for x; do
if test "$x" = CUT; then
set -- # ignore args upto here
else # perhaps more filtering
set -- "$@" "$x"
fi
done
printf "'%s' " "$@"; echo
}
filter "$@"
即我可以在迭代时更改 "$@"
吗? for
复合是否重复隐式数组?
filter 1 2 CUT 3
似乎适用于 dash
、ash
、busybox sh
。
是的,POSIX 确实允许这样做。从标题为 The for Loop 的部分可以推断出(在下面引用,重点是我的)循环保留了它自己要迭代的项目列表的私有副本,并且对 shell 所做的更改执行循环时的执行环境不会对所述副本产生任何影响。
for name [ in [word ... ]] do compound-list done
First, the list of words following
in
shall be expanded to generate a list of items. Then, the variablename
shall be set to each item, in turn, and thecompound-list
executed each time. Omitting:in word...
shall be equivalent to:
in "$@"
换句话说,可以保证程序中的循环遍历位置参数的初始列表,因为 "$@"
的隐含扩展先于 set --
和 set -- "$@" "$x"
。