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

Posted

技术标签:

【中文标题】如何将数组参数传递给 Bash 脚本【英文标题】:How to pass an array argument to the Bash script 【发布时间】:2013-06-18 10:11:30 【问题描述】:

令我惊讶的是,在搜索了 1 小时后我没有找到答案。 我想像这样将一个数组传递给我的脚本:

test.sh argument1 array argument2

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

array=(a b c)
for i in "$array[@]"
do
  test.sh argument1 $i argument2
done

【问题讨论】:

另见***.com/a/1063367/2235132 【参考方案1】:

让你的脚本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[@]"

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

arr=(ab 'x y' 123)
arr2=(a1 'a a' bb cc 'it is one')

并像这样传递参数:

. ./arrArg.sh "foo" "arr[@]" "bar" "arr2[@]"

上面的脚本将打印:

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

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

问。为什么是当前的 shell 环境,为什么不是子 shell?答。因为 bash 不会将数组变量作为 documented here by bash author himself 导出到子进程

【讨论】:

如果任何数组元素包含空格怎么办? @anubhava,非常感谢。我的数组的元素没有空间。但是你和格伦的答案都很好。 当我运行你的代码时,这行的 arg2=("$!2") 我得到了错误的替换 这太棒了,超级聪明,让我的 shell 脚本很棒!【参考方案2】:

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[@]"

然后像这样调用它

test.sh argument1 "$array[@]" argument2

【讨论】:

很好的答案。我知道这不符合 OP 对 test.sh argument1 array argument2 的要求,但如果将调用更改为 test.sh argument1 argument2 array(数组是最后一个),它的工作量就会减少。 好答案。但从技术上讲,它不是将数组传递给脚本。如果 OP 需要像 test.sh argument1 array1 array2 这样将 2 个数组变量传递给这个脚本怎么办? 注意,调用脚本前需要先声明数组。对于 OP,这意味着 $ array=(a b c) 然后是 test.sh argument1 "$array[@]" argument2 。可能只有我需要考虑一下,但我发表评论是希望它对某人有所帮助。【参考方案3】:

如果这是你的命令:

test.sh argument1 $array[*] argument2

您可以像这样将数组读入 test.sh:

arg1=$1
arg2=$2[*]
arg3=$3

它会抱怨你(“糟糕的替代”),但会起作用。

【讨论】:

【参考方案4】:

您可以将数组写入文件,然后在脚本中获取该文件。 例如:

array.sh

array=(a b c)

test.sh

source $2
...

运行 test.sh 脚本:

./test.sh argument1 array.sh argument3

【讨论】:

【参考方案5】:

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

所以我会这样做:

ARRAY=("the first" "the second" "the third")
test.sh argument1 argument2 "$ARRAY[@]"

等同于:

test.sh argument1 argument2 "the first" "the second" "the third"

test.sh 做:

ARG1="$1"; shift
ARG2="$1"; shift
ARRAY=("$@")

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

ARRAY1=(one two three)
ARRAY2=(four five)
test.sh argument1 "$ARRAY1[*]" argument3 "$ARRAY2[*]" 

等同于:

test.sh argument1 "one two three" argument3 "four five"

test.sh 中你可以这样做:

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

我希望这会有所帮助。我写这篇文章是为了帮助(你和我)理解数组是如何工作的,以及 *@ 如何处理数组。

【讨论】:

以上是关于如何将数组参数传递给 Bash 脚本的主要内容,如果未能解决你的问题,请参考以下文章

Perl 如何将数组作为参数传递给另一个 Perl 脚本

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

Redis Lua 脚本 - 如何将数组作为参数传递给 nodejs 中的 Lua 脚本?

如何在 Linux 中使用终端命令将文件参数传递给我的 bash 脚本? [复制]

将可变数量的 bash 命令行参数传递给 MATLAB 函数

如何将文件路径作为 bash 脚本中的参数传递给函数? [复制]