我正在编写一个脚本来执行给定用户输入的CURL命令。该脚本具有多个辅助函数来创建最终将传递给CURL的参数列表(参数)。
一个被剥离的例子如下:
#!/bin/bash
function create_arg_list
{
# THIS HTTP HEADER VALUE COMES FROM THE USER and MAY CONTAIN SPACES
local __hdr="x-madhurt-test:madh urt"
local __params="http://google.co.in -X GET -H '$__hdr'"
local __resultvar="$1"
eval $__resultvar="\"$__params\""
echo "params after eval : $__resultvar"
}
create_arg_list arg_list
echo "params after eval in main code : $arg_list"
echo "Running command : curl -v $arg_list"
curl -v $arg_list
当输入参数(文件路径,网址等)中包含(引用)空格时,脚本运行良好。但是,当应该作为HTTP标头传递给CURL的参数包含空格时,脚本会失败。
这是我尝试过的:
curl -v http://google.co.in -X GET -H 'x-madhurt-test:madh urt',被CURL视为 - 并且发送的实际标头如下所示:
'x-madhurt-test:madh
curl: (6) Couldn't resolve host 'urt"'
有人对此处发生的错误有洞察力吗?
答案 0 :(得分:1)
此代码有效,但不打算按原样使用。我发布它是为了给你一些关于如何进行的想法。他们关键是要做你想做的工作就是使用一个数组。不幸的是,Bash无法从函数返回数组。您可能应该做的是使用全局数组。但是,下面的代码会从declare
语句中创建一个字符串,并将其传递给您的间接变量。这是一个非常糟糕的污泥。
#!/bin/bash
function create_arg_list
{
# THIS HTTP HEADER VALUE COMES FROM THE USER and MAY CONTAIN SPACES
local __hdr="x-madhurt-test:madh urt"
local __params="http://google.co.in -X GET -H"
__params=($__params "$__hdr")
local __resultvar="$1"
eval $__resultvar=$(printf "%q" "$(declare -p __params)")
echo "params after eval : $__resultvar"
}
create_arg_list arg_list
echo "params after eval in main code : $arg_list"
echo "Running command : curl -v $arg_list"
eval $arg_list
curl -v "${__params[@]}"
答案 1 :(得分:1)
丹尼斯的答案很好,所以我会专注于你的代码无效的原因。让我们使用辅助函数来显示函数接收的参数:
$ args() { for x in "$@"; do echo $x; done }
$ args 1 '2 b' 3
1
2 b
3
好的,正如预期的那样,引号仅用于分隔参数。但现在让我们像你一样使用变量:
$ var="1 '2 b' 3"
$ args $var
1
'2
b'
3
Bash扩展变量,函数(或命令)获取引号。当然,这不是你想要的。
解决方案1:使用eval重新解释引号。
$ eval args $var
1
2 b
3
解决方案2:使用数组并使用“$ {MYARRAY [@]}”展开,如Dennis所示。
更多想法:我有时使用的一种技术是在外面做eval:
$ eval "$(create_args_list VARNAME)"
在这种情况下,otherfun将返回一个字符串,当被唤醒时,将创建一个名为VARNAME的变量(甚至可以是本地变量)。此变量(或变量,如果需要)可以是字符串或数组。同样,我会使用一个数组,以便以后可以轻松使用:
$ curl "${VARNAME[@]}"