如何在bash中将空数组作为参数传递

时间:2017-09-06 19:00:29

标签: arrays bash arguments

我正在尝试在bash中编写一个简单的函数,它接受2个参数,一个字符串和一个数组。

在函数开始时,我检查参数的数量

function is2args() {
    if [ $# -le 1 ]; then
        return 1
    fi

    return 0
 }

然后我尝试以下

arr=()
is2args "" "${arr[@]}" # returns 1

由于某种原因,这会触发if语句作为bash认为只有一个参数,但如果列表是空字符串则可以工作

arr=()
is2args "" "" # returns 0

或填充元素

arr=(
     "element"
)
is2args "" "${arr[@]}" # returns 0

并默认为空字符串

arr=()
is2args "" "${arr[@]:-""}" # returns 0

我不太明白发生了什么。我理解这是传递列表的正确方法,但似乎无论出于何种原因,都会忽略空列表。

每次通过数组发送时,我真的应该设置一个默认的空字符串,还是有办法在函数本身中捕获它?

3 个答案:

答案 0 :(得分:3)

这是预期的。 "${arr[@]}"形式展开以将数组的每个元素放在命令行上,并且数组中没有元素。

"${arr[*]}"表单将扩展为一个字符串,其中包含与空格连接的元素(默认情况下)。

您可以尝试这个来测试传递的参数:

$ nargs () {
  local i=0 
  for arg do printf "%d\t>%s<\n" $((++i)) "$arg"; done
}

$ nargs foo "${arr[@]}"
1   >foo<
$ nargs foo "${arr[*]}"
1   >foo<
2   ><

$ arr=(1 2 3)
$ nargs foo "${arr[@]}"
1   >foo<
2   >1<
3   >2<
4   >3<
$ nargs foo "${arr[*]}"
1   >foo<
2   >1 2 3<

$ IFS=,
$ nargs foo "${arr[*]}"
1   >foo<
2   >1,2,3<

答案 1 :(得分:2)

如果要传递固定参数和数组,shift关闭第一个元素; "$@"中剩下的是数组的内容。如果数组为空,$@也将为空。 (如果在$#之后shift为0,则表示数组的长度为0 - 或者没有传递数组;这两种情况完全相同)。

myfn() {
  local string_arg=$1; shift || { echo "ERROR: Initial argument missing" <&2; return 1; }
  local -a array_args=( "$@" )

  echo "Initial argument is: $string_arg"
  echo "Array has length ${#array_args[@]}"
  echo "Array elements:"
  printf ' - %q\n' "${array_args[@]}"
}

array=( "first array member" "second array member" )
myfn "first argument" "${array[@]}"

答案 2 :(得分:2)

您可能希望传递数组的名称(请注意,以下内容需要bash 4.3):

myfunc() {
  local arg1=$1
  local -n array=$2
  printf "first arg: %q\n" "$arg1"
  echo array:
  declare -p array
}

arr=()
myfunc "foo" arr