0

这是一个简单的 Perl 脚本,它接受 2 个参数 - 一个字符串(它是一个 URL)和一个整数值。

我要做的就是在给定的时间段内(以秒为单位)在传递的 URL 上运行 curl 请求。

当 URL 很简单时,一切都很好,http://admin:admin@localhost:5074/?q=james但是当 URL 中有问题时,问题就来&了。

问题是system()即使在退出循环后也使 curl 请求继续运行。

这是怎么回事?

use strict;
use warnings;
use URI::Escape;

my $url = uri_escape($ARGV[0]);
print "URL=".$url."\n"; 
my $duration = $ARGV[1];
print $duration;
my $start = time(); 
my $end = $start + $duration;
my $request = 0;

while(time() <= $end ){ 
    system("curl --user admin:admin --digest ".uri_unescape($url)); 
    $request++;
}

print "------------------------ END ----------------------------------\n";
print "URL = ".uri_unescape($url)." \n";
print "Total requests made = ".$request."\n";
print "Reqs/sec = ".($request/$duration)."/sec \n";
#print $start."\n";
#print $end."\n";
print "Duration = ".$duration." sec \n";
print "-------------------------------------------------------------------\n";

命令是:

perl curl.pl "http://admin:admin@localhost:5074/?q=james&format=xml" 5
4

1 回答 1

8

您的 URL 中有一个&字符被 shell 解释为“在后台运行此命令”。您需要通过以下方式&正确转义元字符,以避免让 shell 解释它们:

use String::ShellQuote qw( shell_quote );
system("curl --user admin:admin --digest " . shell_quote($url)); 

或首选:

system('curl', '--user', 'admin:admin', '--digest', $url);

后者完全避免创建外壳,并直接使用给定的参数进行分叉/执行curl,这些参数会自动转义。它更快、更安全。有关详细信息,请参阅系统 perldoc

顺便说一句,您应该考虑使用LWP。它是较新 Perls 的 Perl 核心的一部分(无需安装),您无需担心转义任何内容。

于 2013-03-15T00:51:16.070 回答