众所周知数组并非 POSIX sh 的一部分,而是 ksh,bash 等的扩展语法。像 ash,dash 等实现就不支持数组。
现在有这么一个需求:需要写一个脚本 myls
代替,编辑命令行参数,将所有的 -q
删掉,把剩下的参数原样转发给 busybox ls
。比如:
1 | myls -q a b |
要将之变换成
1 | busybox ls a b |
还好 POSIX sh 有一个“当前参数数组”的概念,可以用 $1
,$2
这样的方式访问,"$@"
可以完美转发所有参数,不会有空格问题,还有 set
命令可
以用来修改当前参数,但只能一次设置全体参数,无法像数组那样单独修改某个位置。传入的 -q
可能在任意位置,这时我们需要用到 sh 的另一个特性,
for
循环会把要循环的字符串存储一个副本,因此在用 for
循环遍历当前参数时,同时用 set
修改当前参数是安全的。另外,for x do
等同于
for x in "$@"; do
,可以直接遍历当前参数。
这样,我们可以一边遍历当前参数,一边将不等于 -q
的参数添加到当前参数数组的末尾,再用 shift 命令删除初始参数,最后将当前参数传给目标。
1 |
|
另外我们还可以在第一次循环时清空当前参数,这样就不需要在最后用 shift
删除初始参数了:
1 |
|
此处需要 first
变量,我没找到更简单的方法来判断是否是第一次循环。