在 POSIX shell 中,您可以使用参数列表 $@
作为数组
初始化、shift
、unshift
和 push
非常简单:
set -- "item 1" "$variable" *.wav
shift
set -- "new item" "$@"
set -- "$@" "new item"
这是一个
pop
实现示例:
i=0
for last in "$@"; do
if [ $((i+=1)) = 1 ]; then set --; fi
if [ $i = $# ]; then break; fi
set -- "$@" "$last"
done
echo "$last has been removed from ($*)"
($*
将 $@
中的内容使用 $IFS
进行连接,默认情况下为一个空格字符。)
遍历 $@
数组并修改其中一些内容:
i=0
for a in "$@"; do
if [ $((i+=1)) = 1 ]; then set --; fi
a="${a%.*}.mp3"
set -- "$@" "$a"
done
参考 $@
数组中的项目:
echo "$1 is the first item"
echo "$# is the length of the array"
echo "all items in the array (properly quoted): $@"
echo "all items in the array (in a string): $*"
[ "$n" -ge 0 ] && eval "echo \"the ${n}th item in the array is \$$n\""
(eval
很危险,所以在运行之前我确保$n
是一个数字)
有几种方法可以将$last
设置为列表的最后一个项目而不弹出它:
使用函数:
last_item() { shift $(($# - 1)) 2>/dev/null && printf %s "$1"; }
last="$(last_item "$@")"
...或者使用eval
(因为$#
始终是一个数字,所以是安全的):
eval last="\$$#"
...或者使用循环:
for last in "$@"; do true; done
⚠️ 警告: 函数有它们自己的$@
数组。如果是只读的,你必须将其传递给函数,例如my_function "$@"
,否则如果你想操作$@
并且不希望在项值中出现空格,则使用set -- $(my_function "$@")
。
如果需要处理项值中的空格,则变得更加麻烦:
i=1
my_function "$@" |while IFS= read line; do
if [ $i = 1 ]; then unset i; set --; fi
set -- "$@" "$line"
done
这仍然无法处理条目中的换行符。你必须将它们转义成另一个字符(但不是空字符),然后稍后再将它们转义回来。请参见上面的“遍历$@
数组并修改其中一些内容”。你可以在for
循环中遍历数组,然后运行函数,在while IFS= read line
循环中修改变量,或者在for
循环中执行所有操作而不使用函数。
完全错误的
(可能是由 M$ 完成的)。 - David C. Rankinfunction
关键字,神奇的$RANDOM
和echo -n
命令,建议使用trap exit ERR
而不是更有用的trap 'exit 1' ERR
,并且在引用上极其鲁莽。不建议使用。 - Toby Speight