我在使用数组作为参数时遇到问题。
#!/usr/bin/env bash
function array_param
{
local ARRAY_s; local ARRAY_t; local OPTIND
while getopts 's:t:' opt ; do
case "$opt" in
s) ARRAY_s=$OPTARG;;
t) ARRAY_t=$OPTARG;;
esac
done
shift $((OPTIND-1))
echo "ARRAY_s=${ARRAY_s[@]}; ARRAY_t=${ARRAY_t[@]}"
}
array_s=(100 200 300)
array_t=(0 10 3585)
array_param -s ${array_s} -t ${array_t}
为什么只有第一个元素分配给变量ARRAY_s和ARRAY_t?
结果: ARRAY_s = 100; ARRAY_t = 0
答案 0 :(得分:1)
稍微修改函数(对变量使用小写,并使用数组语义)
array_param() {
local l_array_s l_array_t OPTIND
while getopts 's:t:' opt ; do
case "$opt" in
s) l_array_s+=( "$OPTARG" ) ;;
t) l_array_t+=( "$OPTARG" ) ;;
esac
done
shift $((OPTIND-1))
echo "l_array_s=${l_array_s[*]}; l_array_t=${l_array_t[*]}"
}
可以称为
array_param "${array_s[@]/#/-s}" "${array_t[@]/#/-t}"
${array_s[@]/#/-s}
符号特定于bash,#
匹配字符串的开头,并由-s
替换为数组中的每个元素。在printf之后了解如何传递参数
printf "<%s> " "${array_s[@]/#/-s}" "${array_t[@]/#/-t}"
也比较
printf "<%s> " "${array_s}"
printf "<%s> " "${array_s[@]}"
printf "<%s> " "${array_s[*]}"
答案 1 :(得分:0)
${array_s}
相当于${array_s[0]}
,这就是为什么只分配了第一个元素:
#!/usr/bin/env bash
array_param() {
local opt OPTIND tmp
local -a arr_s arr_t
while getopts 's:t:' opt; do
case $opt in
s) tmp=$OPTARG[@]; arr_s=("${!tmp}") ;;
t) tmp=$OPTARG[@]; arr_t=("${!tmp}") ;;
esac
done
echo "arr_s = ${arr_s[*]}"
echo "arr_t = ${arr_t[*]}"
}
arr1=(100 200 300)
arr2=(0 10 3585)
array_param -s arr1 -t arr2
local opt
:您应该对所有变量进行本地化,甚至是opt
tmp=$OPTARG[@]
:创建此格式的临时变量:array_name[@]
arr=(values)
:数组作业${!tmp}
:variable indirection。它首先扩展为$tmp
的值,然后再次展开到最终结果:${!tmp} -> ${array_name[@]} -> all values
您还可以使用nameref(使代码更具可读性,但需要bash
4.3或更高版本):
s) local -n tmp=$OPTARG; arr_s=("${tmp[@]}") ;;
t) local -n tmp=$OPTARG; arr_t=("${tmp[@]}") ;;
答案 2 :(得分:0)
您无法将array_s
和array_t
作为数组传递,getopts
只会获得每个数组的第一个元素。
但是,您可以尝试使用C风格的for
循环来增加本地ARRAY_s
和ARRAY_t
变量,最后将它们打印出来:
$ cat optarg.sh
#!/usr/bin/env bash
function array_param
{
local OPTIND
while getopts 's:t:' opt ; do
case "$opt" in
s) ARRAY_s+=("${OPTARG}");;
t) ARRAY_t+=("${OPTARG}");;
esac
done
shift $((OPTIND-1))
}
array_s=(100 200 300)
array_t=(0 10 3585)
#Works if only array_s length equal array_t length.
for ((args=0; args<${#array_s[@]}; args++))
do
array_param -s ${array_s[args]} -t ${array_t[args]}
done
echo "ARRAY_s=${ARRAY_s[@]}; ARRAY_t=${ARRAY_t[@]}"
输出:
ARRAY_s=100 200 300; ARRAY_t=0 10 3585