如何将数组参数传递给Bash脚本

zhi*_*ong 29 arrays bash arguments

令我惊讶的是,我在1小时后找不到答案.我想将一个数组传递给我的脚本,如下所示:

test.sh argument1 array argument2
Run Code Online (Sandbox Code Playgroud)

我不想把它放在另一个bash脚本中,如下所示:

array=(a b c)
for i in "${array[@]}"
do
  test.sh argument1 $i argument2
done
Run Code Online (Sandbox Code Playgroud)

gle*_*man 30

Bash数组不是"第一类值" - 你不能像一个"东西"那样传递它们.

假设test.sh是一个bash脚本,我会这样做

#!/bin/bash
arg1=$1; shift
array=( "$@" )
last_idx=$(( ${#array[@]} - 1 ))
arg2=${array[$last_idx]}
unset array[$last_idx]

echo "arg1=$arg1"
echo "arg2=$arg2"
echo "array contains:"
printf "%s\n" "${array[@]}"
Run Code Online (Sandbox Code Playgroud)

并调用它

test.sh argument1 "${array[@]}" argument2
Run Code Online (Sandbox Code Playgroud)

  • 好答案.但从技术上讲,它不是将数组传递给脚本.如果OP需要将2个数组变量传递给此脚本,如`test.sh argument1 array1 array2`,该怎么办? (4认同)
  • 请注意,您需要在调用脚本之前声明数组。对于OP,这意味着 `$ array=(abc)` ,然后是 `test.sh argument1 "${array[@]}" argument2` 。可能只有我需要考虑一下,但我发表评论希望它能对某人有所帮助。 (2认同)

anu*_*ava 14

你的脚本arrArg.sh是这样的:

#!/bin/bash

arg1="$1"
arg2=("${!2}")
arg3="$3"
arg4=("${!4}")

echo "arg1=$arg1"
echo "arg2 array=${arg2[@]}"
echo "arg2 #elem=${#arg2[@]}"
echo "arg3=$arg3"
echo "arg4 array=${arg4[@]}"
echo "arg4 #elem=${#arg4[@]}"
Run Code Online (Sandbox Code Playgroud)

现在在shell中设置这样的数组:

arr=(ab 'x y' 123)
arr2=(a1 'a a' bb cc 'it is one')
Run Code Online (Sandbox Code Playgroud)

并传递这样的参数:

. ./arrArg.sh "foo" "arr[@]" "bar" "arr2[@]"
Run Code Online (Sandbox Code Playgroud)

以上脚本将打印:

arg1=foo
arg2 array=ab x y 123
arg2 #elem=3
arg3=bar
arg4 array=a1 a a bb cc it is one
arg4 #elem=5
Run Code Online (Sandbox Code Playgroud)

注意:我使用. ./script语法执行脚本可能看起来很奇怪.请注意,这是用于在当前shell环境中执行脚本的命令.

问:为什么当前的shell环境为什么不是子shell?
答:因为bash不会将数组变量导出到子进程,如bash作者本人所述

  • 如果任何数组元素包含空格怎么办? (5认同)

Fer*_*nch 12

如果值有空格(并且作为一般规则),我投票支持Glenn jackman 的答案,但我会通过将数组作为最后一个参数传递来简化它。毕竟,似乎你不能有多个数组参数,除非你做一些复杂的逻辑来检测它们的边界。

所以我会这样做:

ARRAY=("the first" "the second" "the third")
test.sh argument1 argument2 "${ARRAY[@]}"
Run Code Online (Sandbox Code Playgroud)

与以下内容相同:

test.sh argument1 argument2 "the first" "the second" "the third"
Run Code Online (Sandbox Code Playgroud)

并在test.sh做:

ARG1="$1"; shift
ARG2="$1"; shift
ARRAY=("$@")
Run Code Online (Sandbox Code Playgroud)

如果值没有空格(即它们是 url、标识符、数字等),这里有一个更简单的替代方案。这样你实际上可以拥有多个数组参数,并且很容易将它们与普通参数混合:

ARRAY1=(one two three)
ARRAY2=(four five)
test.sh argument1 "${ARRAY1[*]}" argument3 "${ARRAY2[*]}" 
Run Code Online (Sandbox Code Playgroud)

与以下内容相同:

test.sh argument1 "one two three" argument3 "four five"
Run Code Online (Sandbox Code Playgroud)

test.sh你所做的:

ARG1="$1"
ARRAY1=($2) # Note we don't use quotes now
ARG3="$3"
ARRAY2=($4)
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助。我写这篇文章是为了帮助(你和我)了解数组如何工作以及如何使用数组*@