简体   繁体   English

将数组直接传递给Shell中的函数

[英]Passing an array directly to a function in Shell

is it possible to pass an array directly to a function in shell/bash, without saving it first to a variable? 是否可以将数组直接传递给shell / bash中的函数,而无需先将其保存到变量中?

currently example: 当前示例:

function checkParameter(){
    param1=("${!1}")
    for a in "${param1[@]}"; do
        echo "${a}"
    done

    param2=("${!2}")
    for b in "${param2[@]}"; do
        echo "${b}"
    done
}

a=( "child 1 from 1" "child 2 from 1" "child 3 from 1" )
b=( "child 1 from 2" "child 2 from 2")
checkParameter a[@] b[@]

So can I pass the ( "child 1 from 1" "child 2 from 1" "child 3 from 1" ) and the ( "child 1 from 2" "child 2 from 2") somehow directly to the function checkParameter , without saving it in a and b first? 所以我可以通过某种方式直接将( "child 1 from 2" "child 2 from 2") ( "child 1 from 1" "child 2 from 1" "child 3 from 1" )( "child 1 from 2" "child 2 from 2")传递给函数checkParameter ,而无需保存首先在ab

greetings and thanks, 问候和感谢,
christopher2007 christopher2007

"$1" is immutable. “ $ 1”是不可变的。 That is why your example has to store the value of it in a temporary variable. 这就是为什么您的示例必须将其值存储在一个临时变量中的原因。 This holds true for $@ regardless of whether they are passed as an array or not. 不管$@是否作为数组传递,这对于$@都是正确的。

Are you sure that you need to use an array ? 确定要使用数组吗?

checkparameters() {
    for param in "$@"; do
        echo "$param"
    done
}

checkparameters "a" "b" "c"

To answer the question, I don't think that is possible to pass an array as function's args without transformations. 要回答这个问题,我认为在不进行转换的情况下将数组作为函数的args传递是不可能的。

EDIT 编辑

You could try something like : 您可以尝试类似:

[ ~]$ cat test.sh 
#!/bin/bash 

declare -a a1
a1=("a" "b")

declare -a a2
a2=("c" "d")

checkParameters(){
    for i in "$@"; do
        echo "Content of $i :"
        for j in $(eval "echo \${$(echo $i)[@]}"); do
            echo $j
        done
    done
}

checkParameters "a1" "a2"
[ ~]$ ./test.sh 
Content of a1 :
a
b
Content of a2 :
c
d

Generally, you cannot pass arrays to Bash scripts or functions as arrays : 通常,您不能将数组传递给Bash脚本或作为数组的函数:

When you pass an array on the command line, eg, "${ary[@]}" , you're not passing an array , but its elements as individual parameters ; 当您在命令行中传递数组时,例如"${ary[@]}" ,您没有传递数组 ,而是将其元素作为单独的参数传递; the first array element is bound to special parameter $1 , the second to $2 , ... 第一个数组元素绑定到特殊参数$1 ,第二个元素绑定到$2 ,...

Your solution attempt employs a clever workaround by passing the name of array variables to the function, where variable indirection ( ${!...} ) is used to access the array inside the function. 您的解决方案尝试通过将数组变量名称传递给函数来采用巧妙的解决方法,其中使用变量间接寻址${!...} )来访问函数内部的数组。 [1] [1]

By definition, this approach requires the arrays to be stored in variables up front. 根据定义,此方法要求将数组预先存储在变量中

As for your desire to do it without storing your arrays in a variable : You cannot pass array literals as arguments in Bash; 至于您希望不将数组存储在变量中的愿望:您不能将数组文字作为Bash中的参数传递; the conceptual equivalent of that is to simply pass individual parameters . 在概念上等效的是简单地传递各个参数

The problem with that is that you won't be able to tell where the elements of one array end and the next one begins . 这样做的问题是, 您将无法分辨一个数组的元素在哪里结束而下一个数组的元素在哪里开始

You can address that by introducing a separator parameter whose sole purpose is to indicate when an array ends. 您可以通过引入分隔符参数来解决该问题,该参数的唯一目的是指示数组何时结束。

For instance, if you know that your elements never contain a newline, you can use $\\n as the separator: 例如,如果您知道元素永远不会包含换行符,则可以使用$\\n作为分隔符:

#!/usr/bin/env bash

function checkParameter(){
  local -i arrayNdx=1
  for param; do # Loop over all parameters
    [[ $param == $'\n' ]] && { (( ++arrayNdx )); continue; }
    echo "From array $arrayNdx: [$param]"
  done  
}

# Pass the array elements as individual parameters
# and use $'\n' (a newline) to separate the elements of the 1st
# array from those of the 2nd.
checkParameter "a1-child 1" "a1-child 2" "a1-child 3" $'\n' "a2-child 1" "a2-child 2"

[1] Just to show a simplified version of your solution to make the variable-indirection part clearer: [1]只是为了展示您的解决方案的简化版本,以使变量间接部分更加清晰:

function checkParameter(){
    for a in "${!1}"; do
        echo "${a}"
    done

    for b in "${!2}"; do
        echo "${b}"
    done
}

checkParameter a[@] b[@]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM