在 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

似乎适用于 dashashbusybox 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"