我正在编写一个简单的bash shell脚本;它输出url的页面加载时间。只有在使用特定自定义标头请求时,服务器才会响应正确的页面(仅供参考:缺少标头,默认页面由服务器提供。) 访问的网址&它的头文件是从配置文件中读取的(用分号分隔) 样本条目:http://google.com/;User-Agent:XYZ A; msisdn:98xxxxxxxx
我做了所有事情,从阅读文件到解雇wget命令。
然而,查看输出我发现,header字符串未正确传递(尽管我正确构建它)到wget命令。 在进一步调试时,我发现bash / linux in-tern将整个头字符串包装成单引号并将其发送到wget命令,因为wget未能给出预期的输出。
代码:
#!/bin/bash
load_page()
{
echo "url=$url";
echo "headers=$header_str";
/usr/bin/time -f "\t%e\t%C" wget -kKHpq --no-cache "$header_str" "$url"
}
read_config_file()
{
while read cfg_line
do
if [[ ! "$cfg_line" = \#* ]] && [[ "x$cfg_line" != "x" ]] ; then
url=`echo $cfg_line | cut -d";" -f1`
fields=`echo $cfg_line | awk -F";" ' { print NF } ' `;
f_cnt=2;
unset header_str
while [ $f_cnt -le $fields ] ;
do
field=`echo $cfg_line | cut -d";" -f$f_cnt`;
header_name=`echo $field | cut -d":" -f1`;
header_val=`echo $field | cut -d":" -f2`;
header_str="${header_str}--header=\"${header_name}: $header_val\" "
f_cnt=`expr $f_cnt + 1`;
done
load_page
fi
done<urls.cfg
}
main()
{
read_config_file
}
main $@
输出:
url=http://some-website.com/
headers=--header="User-Agent: XYZ G" --header="msisdn: 98xxxxxxxx"
6.37 wget -kKHpq --no-cache --header="User-Agent: XYZ G" --header="msisdn: 98xxxxxxxx" http://some-website.com/
每件事看起来都不错,但是没有提取正确的页面。如果我从输出中复制粘贴命令,则服务器将响应预期的页面。
在调试模式下运行shell脚本时;我认为这是问题所在。标题字符串被包装到wget命令中的单引号中。
请帮忙。
+ load_page
+ echo url=http://some-website.com/
url=http://some-website.com/
+ echo 'headers=--header="User-Agent: XYZ G" --header="msisdn: 98xxxxxxxx" '
headers=--header="User-Agent: XYZ G" --header="msisdn: 98xxxxxxxx"
+ /usr/bin/time -f '\t%e\t%C' wget -kKHpq --no-cache '--header="User-Agent: XYZ G" --header="msisdn: 98xxxxxxxx" ' http://some-website.com/
1.66 wget -kKHpq --no-cache --header="User-Agent: XYZ G" --header="msisdn: 98xxxxxxxx" http://some-website.com/
答案 0 :(得分:0)
你是在引用字符串,如果删除引号会怎么样?
/usr/bin/time -f "\t%e\t%C" wget -kKHpq --no-cache $header_str "$url"
引用的任何内容都应作为单个参数(字符串)传递。所以如果它没有引用,它应该评估并将它们作为单独的参数传递
答案 1 :(得分:0)
$header_str
被解释为单个参数,因为它包含在引号中。
尝试将您的wget命令更改为:
/usr/bin/time -f "\t%e\t%C" wget -kKHpq --no-cache $header_str "$url"
即使输出结果如下:
wget -kKHpq --no-cache --header="User-Agent: XYZ G" --header="msisdn: 98xxxxxxxx" http://some-website.com/
传递给进程的argv
数组的参数看起来像这样:
[ "wget", "-kKHpq", "--no-cache" "-header=\"User-Agent: XYZ G\" --header=\"msisdn: 98xxxxxxxx\", "http://some-website.com/" ]
答案 2 :(得分:0)
我建议使用eval
。为此,您需要将完整命令构建为将传递给eval
的字符串。我不是在用wget写出完整示例的地方,但基本的想法是:
my_args='-al'
eval "ls ${my_args}"
如果您从这个基本示例开始,我认为您会发现可以将命令的固定方面与配置中的用户字符串可靠地结合起来。
关于使用eval
,exec
和source
的讨论虽然篇幅但内容丰富,但我建议您阅读bash shell: 'exec', 'eval', 'source' - looking for help to understand