bash 将多个不同的数组传递给 shell 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10953833/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 02:27:45  来源:igfitidea点击:

Passing multiple distinct arrays to a shell function

bash

提问by Charles Duffy

Because shells other than ksh do not support pass-by-reference, how can multiple arrays be passed into a function in bash without using global variables, and in a way which allows any legal variable content to be included as an array element (no reserved sigils)?

因为 ksh 以外的 shell 不支持按引用传递,如何在不使用全局变量的情况下将多个数组传递到 bash 中的函数中,并且以允许将任何合法变量内容作为数组元素包含在内的方式(无保留)印记)?

回答by Charles Duffy

Since bash 4.3

由于 bash 4.3

As of 2016, modern bash supports pass-by-reference (a.k.a namerefattribute) as:

截至 2016 年,现代 bash 支持传递引用(又名nameref属性)为:

demo_multiple_arrays() {
  local -n _array_one=
  local -n _array_two=
  printf '1: %q\n' "${_array_one[@]}"
  printf '2: %q\n' "${_array_two[@]}"
}

array_one=( "one argument" "another argument" )
array_two=( "array two part one" "array two part two" )

demo_multiple_arrays array_one array_two

See also declare -nin the man page.

另请参见declare -n手册页。



Before bash 4.3

在 bash 4.3 之前

This can be done safely by using a calling convention which puts number-of-arguments before each array, as such:

这可以通过使用调用约定安全地完成,该约定将参数数量放在每个数组之前,如下所示:

demo_multiple_arrays() {
  declare -i num_args array_num;
  declare -a curr_args;
  while (( $# )) ; do
    curr_args=( )
    num_args=; shift
    while (( num_args-- > 0 )) ; do
      curr_args+=( "" ); shift
    done
    printf "$((++array_num)): %q\n" "${curr_args[@]}"
  done
}

This can then be called as follows:

这可以被称为如下:

array_one=( "one argument" "another argument" )
array_two=( "array two part one" "array two part two" )
demo_multiple_arrays \
  "${#array_one[@]}" "${array_one[@]}" \
  "${#array_two[@]}" "${array_two[@]}"

回答by Fritz G. Mehner

Can also be done using eval:

也可以使用 eval 来完成:

declare -a a=( "aa bb" 123 '$ $ $' )
declare -a b=( "bb cc" 456 '###' )

printf "\n%s\n" 'a before sub:'
printf "'%s'\n" "${a[@]}"
printf "\n%s\n" 'b after sub:'
printf "'%s'\n" "${b[@]}"


sub ()
{
  eval a0=${[0]}                     # get value a[0]
  eval b1=${[1]}                     # get value b[1]
  echo "a[0] = '$a0'"
  echo "b[1] = '$b1'"

  eval [0]='a---a'                    # set value a[0]
  eval [1]=999                        # set value b[1]

} # ----------  end of function sub  ----------

sub a b     # call function sub

printf "\n%s\n" 'a after sub:'
printf "'%s'\n" "${a[@]}"
printf "\n%s\n" 'b after sub:'
printf "'%s'\n" "${b[@]}"

The output:

输出:

a before sub:
'aa bb'
'123'
'$ $ $'

b after sub:
'bb cc'
'456'
'###'
a[0] = 'aa bb'
b[1] = '456'

a after sub:
'a---a'
'123'
'$ $ $'

b after sub:
'bb cc'
'999'
'###'