Bash 通过要使用getopts()处理的命令行传递数组

Bash 通过要使用getopts()处理的命令行传递数组,bash,Bash,我尝试向.bash文件传递一些参数 terminal: arr=("E1" "E2" "E3") param1=("foo") param2=("bar") execute.bash -a ${arr[@]} -p $param1 -c param2 现在我想调用execute.bash文件 terminal: arr=("E1" "E2" "E3") param1=("foo") param2=("bar") execute.bash -a ${arr[@]} -p $param1

我尝试向.bash文件传递一些参数

terminal:

arr=("E1" "E2" "E3")
param1=("foo")
param2=("bar")
execute.bash -a ${arr[@]} -p $param1 -c param2
现在我想调用execute.bash文件

terminal:

arr=("E1" "E2" "E3")
param1=("foo")
param2=("bar")
execute.bash -a ${arr[@]} -p $param1 -c param2
这是我的档案:

execute.bash:
while getopts ":a:p:c:" opt; do
    case $opt in
        a) ARRAY=${OPTARG};;
        p) PARAM1=${OPTARG};;
        c) PARAM2=${OPTARG};;
        \?) exit "Invalid option -$OPTARG";;
    esac
done

for a in "${ARRAY[@]}"; do
    echo "$a"
done

echo "$PARAM1"
echo "$PARAM2"
但我的文件只打印:

E1
foo
bar

我的脚本有什么问题?

如果我想导出数组my_数组,我在调用方使用:

[[ $MY_ARRAY ]] && export A_MY_ARRAY=$(declare -p MY_ARRAY)
SUB_SCRIPT "$(declare -p MY_ARRAY)"
。。。在子脚本端:

[[ $A_MY_ARRAY =~ ^declare ]] && eval $A_MY_ARRAY
[[ $1 =~ ^declare ]] && eval $1
这个概念也适用于参数。在呼叫方:

[[ $MY_ARRAY ]] && export A_MY_ARRAY=$(declare -p MY_ARRAY)
SUB_SCRIPT "$(declare -p MY_ARRAY)"
。。。在子脚本端:

[[ $A_MY_ARRAY =~ ^declare ]] && eval $A_MY_ARRAY
[[ $1 =~ ^declare ]] && eval $1

这两种解决方案的唯一问题是,两边的变量名是相同的。如果在展开之前替换变量名,则可以更改此设置。

使用${arr[@]}展开数组中的所有值将每个值作为单独的命令行参数展开,因此getopt仅将第一个值视为“-a”选项的参数

如果使用${arr[*]}展开,则所有数组值都会展开为单个命令行参数,因此getopt可以将数组中的所有值作为“-a”选项的单个参数来查看

还有几个其他问题:您需要在命令行中引用值:

< execute.bash -a ${arr[@]} -p $param1 -c param2
> execute.bash -a "${arr[*]}" -p $param1 -c $param2

我认为这正是您所期望的。

您在将数组作为
-a
标志的参数之一传递时遇到问题。调用实际脚本之前,
bash
中的数组在命令行中展开。
“${array[@]}”
扩展输出用空格分隔的字

因此,您的脚本作为

-a "E1" "E2" "E3" -p foo -c bar
因此,使用
getopts()
调用
-a
的参数
OPTARG
,填充的值不会超过第一个值,即仅
E1
。实现这一点的一种方法是使用类型为
“${array[*]}”
的数组扩展,它将字符串与默认的
IFS
(空白)连接起来,这样
-a
现在可以看到一个字符串与连接的数组的字,即好像作为

-a "E1 E2 E3" -p foo -c bar
我已经强调了为
显示arg的报价-将在
getopts()中收到一个

并作为

-a "${arr[*]}" -p "$param1" -c "$param2"

需要注意的是,确保数组
arr
中的单词不包含包含空格的单词。在这种情况下,如上所述将它们读回会有拆分这些单词的问题,因为
IFS
bash
中处理的性质不同。在这种情况下,在传递阵列扩展时,请使用不同的de限制器,例如
|
#

@ini感谢您的反馈。重新打开。此答案也适用。但它比公认的要长一点。但是谢谢你!