2010-07-06 74 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