bash - 使用变量 int 值来引用函数中的位置参数

Cyb*_*beX 3 shell bash shell-script

我想用一个变量说:

i=1
Run Code Online (Sandbox Code Playgroud)

作为引用传递给脚本的位置变量的值,例如:

x=101
y=201
z=301

foo(){
    echo "$1"
    echo "$2"
    echo "$3"
}

foo x y z
Run Code Online (Sandbox Code Playgroud)

输出:

101
201
301
Run Code Online (Sandbox Code Playgroud)

不是通过索引引用每个参数,我如何使用i作为索引变量递增?

澄清:

foo() {
    local i=1
    echo "$i" #echo first paramter
    (( i+=1 ))
    echo "$i" #echo second parameter
    #etc.
}
Run Code Online (Sandbox Code Playgroud)

echo "$i"部分的语法是什么?

@Eric回答后更新

~$ t=5
~$ foo() { i=1; echo "${!i}"; }
~$ foo t
t
~$
Run Code Online (Sandbox Code Playgroud)

更新 #2

简而言之,我可以使我的方法起作用的唯一方法是:

foo() { #assuming 3 parameters

    i=0
    (( i+=1 ))
    var="${!i}"
    echo "${!var}"

    (( i+=1 ))
    var="${!i}"
    echo "${!var}"

    (( i+=1 ))
    var="${!i}"
    echo "${!var}"        
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ouf 5

这类似于此处的 SO 问题,类似于 @costas 评论。您可以使用$#获取参数的数量,然后使用间接引用,例如${!i}按名称访问变量。下面是一个例子:

f() {
    for((i=1; i<=$#; i++)); do
        printf "%d %s\n" "$i" "${!i}"
    done
}

f a b c
Run Code Online (Sandbox Code Playgroud)

打印:

1 a
2 b
3 c
Run Code Online (Sandbox Code Playgroud)

既然您想将变量的名称作为位置参数传入,您可以像这样额外增加一层间接引用:

a=first
b=second
c=third

f() {
    for((i=1; i<=$#; i++)); do
        var="${!i}"
        printf "%d %s\n" "$i" "${!var}"
    done
}

f a b c
Run Code Online (Sandbox Code Playgroud)

哪个打印

1 first
2 second
3 third
Run Code Online (Sandbox Code Playgroud)

这让我们将每个参数视为一个变量的名称,我们将其存储在var此处。然后我们在printf.

一次只能获得一层间接,嵌套不起作用。所以试图一举完成它是${!${!i}}行不通的,因为第一个{开始扩展,其余的被视为要扩展的 PARAMETER 值。第一个字符是!它会将其余字符视为包含我们想要的参数名称的 PARAMETER 的名称,但${!i}不是有效的参数名称,因此我们得到一个bad substitution. 所以我们只需分两步来避免这个问题。