2010-07-06 72 views
1

我正在编写一个脚本来为给定的用户输入执行CURL命令。脚本有多个帮助函数来创建最终传递给CURL的参数列表(参数)。Bash,curl,eval和whitespace

一个剥离出来例子,如下:

#!/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的参数包含空格时,脚本将失败。

这里是我试过:

  1. 周围使用标头值(例如 '$ __ HDR')单引号。但是,传递给CURL的值是:
    curl -v http://google.co.in -X GET -H 'x-madhurt-test:madh urt'
    ,它被视为CURL,并且实际发送的头是这样的:
    'x-madhurt-test:madh
  2. 双转义标头值(例如\\“$ __ hdr \\“),但这似乎也起作用。在这种情况下,CURL将“urt”作为一个单独的参数并将其视为一个URL
    curl: (6) Couldn't resolve host 'urt"'
  3. 转义标题值中的空格(即使用“madh urt”而不是“madh urt”),但事实证明与选项2相同。

有人对此处发生了什么问题有所了解吗?

+0

仅供参考:我使用eval来返回变量来自以下文章:http://www.linuxjournal.com/content/return- values-bash-functions – madhurtanwani 2010-07-06 15:23:35

回答

1

此代码有效,但并不打算按原样使用。我张贴它给你一些想法,你可以继续。他们的关键是让你想做的工作是使用一个数组。不幸的是,Bash不能从函数返回数组。你可能应该做的是使用全局数组。但是,下面的代码会创建一个字符串,并将其传递给您的间接变量。这是一个严重的烂kludge。

#!/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[@]}" 
+0

感谢Dennis的脚本。我会穿过它并理解。 你能帮我理解为什么我写的代码不能正常工作吗?我想了解那里的小故障/技术问题。 感谢并感谢您的时间来回答这个问题! – madhurtanwani 2010-07-06 20:09:57

1

丹尼斯的回答很好,所以我会专注于为什么你的代码不起作用。让我们使用辅助函数来显示函数收到的参数:

$ args() { for x in "[email protected]"; 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将返回一个字符串,evaled时,将创建名为varName的变量(可以甚至是本地的)。这个变量(或变量,如果需要的话)可以是字符串或数组。再次,我会使用一个数组,以便以后可以轻松使用它:

$ curl "${VARNAME[@]}" 
+0

感谢您的解释。让事情变得清晰! – madhurtanwani 2010-09-09 08:14:46