我正在运行我的脚本script.sh 12345 12346 12347
for z in 1..$(seq 1 $#);
do
echo "param $z is $($(echo $z))"; //Line 4
done;
我期望输出如下:
param 1 is 12345
param 2 is 12346
param 3 is 12347
我猜,我在第 4 行遗漏了一些东西。
答案1
问题在于$($(echo $z))
它首先扩展为$(1)
(如果$z
是 1),然后 shell 尝试1
作为命令运行。
假设bash
:
params=( "$@" )
for (( i = 0; i < ${#params[@]}; ++i )); do
printf 'Param %d is "%s"\n' "$i" "${params[i]}"
done
运行它:
$ bash script.sh a b c
Param 0 is "a"
Param 1 is "b"
Param 2 is "c"
或者,与/bin/sh
:
i=0
while [ "$#" -gt 0 ]; do
printf 'Param %d is "%s"\n' "$i" "$1"
i=$(( i + 1 ))
shift
done
运行:
$ /bin/sh script.sh a b c
Param 0 is "a"
Param 1 is "b"
Param 2 is "c"
那是如果您确实需要显式枚举它们。通常我们会循环"$@"
:
for param in "$@"; do
printf 'Param: "%s"\n' "$param"
# do other thing with "$param" here
done
答案2
for z in 1..$(seq 1 $#);
对于三个参数,这将扩展为1..1
, 2
, 。已经将数字打印为不同的单词,并且无法真正生成数字列表。大括号扩展可以生成数字列表,语法是,但在 Bash 中它不支持其中的变量。3
seq
for
{1..3}
所以这可以写成
for z in $(seq $#) ; do ... # or
for (( z=1 ; z <= $# ; z++ )) ; do ...
或者在 ksh 或 zsh 中使用大括号:
for z in {1..$#} ; do ...
如果你想间接引用一个变量,你可以使用${!var}
(在 Bash 中)wherevar
保存姓名变量的,所以例如
echo "param number $z is ${!z}"
或者,您可以使用切片符号$@
(应该在 Bash/ksh/zsh 中工作):
echo "param number $z is ${@:z:1}"
但实际上,仅使用for x in "$@"
循环遍历值可能被认为更惯用。添加编号也相当简单,无需任何特定于 shell 的功能:
i=1
for x in "$@" ; do
echo "param $i is $x"
i=$((i+1))
done