【问题标题】:How to execute CURL command from a perl script?如何从 perl 脚本执行 CURL 命令?
【发布时间】:2018-12-12 17:15:52
【问题描述】:

我想在部署完成后立即预热我的服务,否则第一个点击我的服务的人会面临很大的延迟。

为此,我想执行类似于以下的 curl 命令:

curl -v -H "Accept:text/x-html-parts,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8" -H "Accept-Charset:UTF-8" -H "Accept-Encoding:identity" -H "Connection:Keep-Alive" -H "Via:HTTP/1.1 ShoppingArea" + + + something.. something....

此 curl 脚本将在部署过程中执行,并将调用我的服务的主 spring 控制器。

我想把这个命令写在一个 perl 文件中。

但我不太确定该怎么做!

任何线索都会有所帮助:)

【问题讨论】:

  • 在纯 perl 中可能会更好... LWP::UserAgent 或类似模块。哎呀,甚至可能有一个 libcurl 绑定......
  • 使用 corion.net/curl2lwp.psgi ,您可以使用 LWP::UserAgent 轻松地将 Curl 命令行转换为 Perl 脚本。评论框对于生成的代码来说太小了,但是如果这是您要查找的内容,我可以将其发布为答案。
  • @Corion 如果您预先将其作为答案,那将是非常可观的! :)
  • curl 只是 libcurl 库的包装器。为什么不直接使用libcurl库而不是炮轰呢? Net::Curl.

标签: spring perl curl optimization controller


【解决方案1】:

作为在纯 Perl 中重现 curl 的粗略原型(使用 https://corion.net/curl2lwp.psgi ),您可以使用 LWP::UserAgent 轻松地将 Curl 命令行转换为 Perl 脚本:

#!perl
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request;


my $ua = LWP::UserAgent->new();
my $r  = HTTP::Request->new(
    'GET' => 'https://api.example.com/',
    [
        'Connection' => 'Keep-Alive',
        'Via'        => 'HTTP/1.1 ShoppingArea',
        'Accept' =>
'text/x-html-parts,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Charset'  => 'UTF-8',
        'Accept-Encoding' => 'identity',
        'Host'            => 'api.example.com:443',
        'User-Agent'      => 'curl/7.55.1',
    ],

);
my $res = $ua->request( $r, );


__END__

Created from curl command line
curl -v -H "Accept:text/x-html-parts,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8" -H "Accept-Charset:UTF-8" -H "Accept-Encoding:identity" -H "Connection:Keep-Alive" -H "Via:HTTP/1.1 ShoppingArea" https://api.example.com/ 

这需要LWP::UserAgent 模块,因此使用curl 可能仍然是一种更快的方法。如果您需要对结果做出反应,例如在 HTTP 错误 500 上发送错误邮件或在 HTTP 错误 4xx 上发送其他通知,使用纯 Perl 会更方便,因为您可以直接返回状态码。

【讨论】:

  • 当我尝试运行上述脚本时,我得到“java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens”作为错误。我想这是由于“|”的存在(管道)字符。我怎样才能摆脱这个?
  • 这是一条 Java 错误消息。你从哪里得到那个 Java 错误信息?上面的脚本是一个 Perl 脚本。
  • 感谢您的帮助!你能告诉我,我怎么能确定这个脚本是否成功执行?
  • @GauravSetia 这更像是一个调试问题 - 我不知道如何调试 Java 脚本,但您可以通过 print $res->is_successexit $res->is_successprint $res->code 查看/指示请求状态。
【解决方案2】:

不好的做法,但使用system(运行任意shell代码):

system "curl -v -H 'Accept:text/x-html-parts,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8' -H 'Accept-Charset:UTF-8' -H 'Accept-Encoding:identity' -H 'Connection:Keep-Alive' -H 'Via:HTTP/1.1 ShoppingArea' + + + something.. something...."

另外,来自 (How do I write a Perl script to use curl to process a URL?):

my $curl=`curl http://whatever`

【讨论】:

    【解决方案3】:

    如果你只想在你的 Perl 脚本中使用特定的 CURL。我建议您使用反引号执行系统调用。

    my $curlcomm = `curl -v -H "Accept:text/x-html-parts,text/html,application/xhtml+xml,applicatio/xml;q=0.9,image/webp,image/apng,*/*;q=0.8" -H "Accept-Charset:UTF-8" -H "Accept-Encoding:identity" -H "Connection:Keep-Alive" -H "Via:HTTP/1.1 ShoppingArea" + + + something.. something....`
    

    但也可以使用标准方法,可以使用LWP::UserAgentLWP::Curl 和类似方法。

    【讨论】: