我正在尝试将字符串数组传递给Bash中的函数,导致“意外令牌附近的语法错误”('“
#!/usr/bin/env bash
function __test() {
my_command -c ("a" "b" "c" "d")
}
我在这里做错了什么?
答案 0 :(得分:2)
您不能让Bash通过引用传递数组,也不能将其复制为单个实体。
有两种方法可以达到预期的效果。
第一个是复制数据
function __test()
{
declare -a array=("a" "b" "c" "d")
my_command -c "${array[@]}"
}
my_command()
{
# Handle options
[[ "$1" != -c ]] || shift
# Get your data back in array form by collecting
# positional parameters in an array
declare -a array=("$@")
# Display element at position 2
echo "${array[2]}"
# Display all elements
echo "${array[@]}"
}
如果mycommand
是另一种语言的外部程序,那么您将收到数据作为位置参数。
第二种方法是间接方法,只有在同一个Bash脚本中使用数据才能使用,以便变量可以在同一范围内访问。
function __test()
{
declare -a array=("a" "b" "c" "d")
my_command -c array
}
my_command()
{
# Handle options
[[ "$1" != -c ]] || shift
varname="$1"
# Access element at position 2
x="$varname[2]"
echo "${!x}"
# Access all elements
x="$varname[@]"
echo "${!x}"
}
您需要确保使用的变量名称不包含任何不需要的数据,否则可能存在风险或代码注入,因此除非变量名完全在您的程序控制之下(不包括用户输入的可能性)在变量名中),你必须找到一种方法来消毒它。
bash的最近变量在变量声明语句(例如-n
)中有一个local
选项,您可能也想看一下它,但我认为这个选项的部署范围不够广泛除已知配置外,请使用。
请注意,我通常会在函数中声明所有变量local
,除非我有特殊原因不这样做,为了清楚起见,上面的代码中已经省略了这一点。
答案 1 :(得分:1)
这是违反语法的行为,
function __test() {
my_command -c "a" "b" "c" "d"
}
将四个字符串传递给my_command
。 ()
是bash
中的语法,用于在子shell下执行,这可能不适用于此。
(或)使用数组
function __test() {
local myArray=("a" "b" "c" "d" )
my_command -c "${myArray[@]}"
}
您使用数组的想法是正确的,但将整个数组作为${myArray[@]}
传递给命令。
您要求getopts
来处理此问题,以下是您处理此问题的方法。有两种方法可以做到这一点,
将参数作为单引号字符串“a b c d”
传递usage() { echo "Usage: $0 [-c args]" 1>&2; exit 1; }
[ $# -eq 0 ] && usage
while getopts ":c:" arg; do
case $arg in
c)
IFS=' '
argsC=($OPTARG)
;;
*)
usage; exit 0
;;
esac
done
printf "%s\n" "Number of arguments: ${#argsC[@]}"
现在正在运行,
./script.sh -c "a b c d"
Number of arguments: 4
a
b
c
d
并且要作为多个字符串发送,请将OPTARG
值添加到数组中,单独更改getopts
部分,
while getopts ":c:" arg; do
case $arg in
c)
argsC+=($OPTARG)
;;
*)
usage; exit 0
;;
esac
done
现在运行脚本,
./script.sh -c "a" -c "b" -c "c" -c "d"
Number of arguments: 4
a
b
c
d
du
使用此 [shell check] 网站在语法上验证您的脚本。