【问题标题】:Curl crashes when running under cron在 cron 下运行时 curl 崩溃
【发布时间】:2012-04-02 14:18:56
【问题描述】:

我遇到了一个非常奇怪的问题,我已经用谷歌搜索了这个问题,但我终生无法找到答案。我是编程新手(不到 2 年),如果这很明显,或者我没有提供足够的细节,我很抱歉

问题是... 当我在 while 循环中第五次调用 curl 时(从 root 的 cron 运行时),curl 崩溃。 当我在登录时手动运行所说的 while 循环时 curl 很好(大约 50 次迭代)。

我从 cron 运行一个 bash 脚本 bash 脚本运行 perl 脚本 perl 脚本在 while 循环中调用 curl 在此 while 循环的第 5 次迭代中,调用 curl 并崩溃(无输出)

  • 我正在以 root 身份运行 cron (crontab -u root /path/to/the/crontab/file)
  • 我不认为它是基于环境的,因为它运行良好 4 次
  • 如果我在 4 次迭代中结束 while 循环并重新启动它,它仍然会失败,所以我认为问题不在于 while 循环。
  • 这个确切的脚本在我运行 Ubuntu 桌面的旧服务器上运行良好(我现在在 Ubuntu 服务器 10.04 上)
  • 我认为这是 curl 和 cron 之间的问题。

crash 的行看起来是这样的(vars 填写)

$err = system("/usr/bin/curl -f -v -s -r "36155357-36259993,36790101-37194555,53623979-53745261" http://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.2012040100/master/gfs.t00z.mastergrb2f21 -o /root/Desktop/getGFS_uploadGFS/GFS/windvect/gfs.t00z.mastergrb2f21.tmp");

我现在完全被难住了,如果有人有任何想法,将不胜感激。下面是 while 循环(崩溃点在底部附近突出显示)。

while ($fhr <= $hr1) {
   if ($fhr <= 9) { $fhr="0$fhr"; }
   $url = $URL;
   $url =~ s/\$FHR/$fhr/g;
   $url =~ s/\${FHR}/$fhr/g;
   $file = $url;
   $file =~ s/^.*\///;

   #
   # read the inventory
   #    $line[] = wgrib inventory,  $start[] = start of record (column two of $line[])
   #

   if ($windows eq 'yes') {
      $err = system("$curl -f -s $url$inv -o $OUTDIR/$file.tmp");
      $err = $err >> 8;
      if ($err) {
          print STDERR "error code=$err,  problem reading $url$inv\n";
         sleep(10);
         exit(8);
      }
  open (In, "$OUTDIR/$file.tmp");
   }
   else {
      open (In, "$curl -f -s $url$inv |");
   }

   $n=0;
   while (<In>) {
      chomp;
      $line[$n] = $_;
      s/^[^:]*://;
      s/:.*//;
      $start[$n] = $_;
      $n++;
   }
   close(In);
   if ($n == 0) {
       print STDERR "Problem reading file $url$inv\n";
       sleep(10);
       exit(8);
   }

   #
   # find end of record: $last[]
   #

   $lastnum = $start[$n-1];
   for ($i = 0; $i < $n; $i++) {
      $num = $start[$i];
      if ($num < $lastnum) {
         $j = $i + 1;
         while ($start[$j] == $num) { $j++; }
         $last[$i] = $start[$j] - 1;
      }
      else {      
         $last[$i] = '';
      }
   }

   if ($action eq 'inv') {
      for ($i = 0; $i < $n; $i++) {
         print "$line[$i]:range=$start[$i]-$last[$i]\n";
      }
      exit(0);
   }

   #
   # make the range field for Curl
   #

   $range = '';
   $lastfrom = '';
   $lastto = '-100';
   for ($i = 0; $i < $n; $i++) {
      $_ = $line[$i];
      if (/$LEVS/i && /$VARS/i) {
         $from=$start[$i];
         $to=$last[$i];

         if ($lastto + 1 == $from) {
            $lastto = $to;
         }
         elsif ($lastto ne $to) {
            if ($lastfrom ne '') {
               if ($range eq '') { $range = "$lastfrom-$lastto"; }
               else { $range = "$range,$lastfrom-$lastto"; }
            }
            $lastfrom = $from;
            $lastto = $to;
        }
      }
   }
   if ($lastfrom ne '') {
      if ($range eq '') { $range="$lastfrom-$lastto"; }
      else { $range="$range,$lastfrom-$lastto"; }
   }


   if ($range ne '') {


    #################################################################################
    ########### THE BELOW LINE IS WHERE CURL IS CALLED AND IT CRASHES ###############
    #################################################################################


      $err = system("$curl -f -v -s -r \"$range\" $url$grb -o $OUTDIR/$file.tmp");
      $err = $err >> 8;
      if ($err != 0) {
         print STDERR "error in getting file $err $url$grb\n";
         sleep(20);
         exit $err;
      }
      rename "$OUTDIR/$file.tmp", "$OUTDIR/$file";
      $output = "$output $OUTDIR/$file";
   }
   else {
      print "no matches (no download) for $file\n";
   }
   $fhr += $dhr;
}

【问题讨论】:

  • “崩溃”是什么意思?有核心转储吗?给标准错误的消息?如果是后者,请准确发布。如果是前者,安装调试符号并收集堆栈跟踪会很有用。
  • 还有一件事:system的返回值是多少?
  • 好的,@CharlesDuffy 你已经解决了这个问题。由于某种原因,尝试写入标准错误时,崩溃发生在第 5 次迭代中。当我使用script.pl &gt;&gt; log00.log 2&gt;&amp;1 重定向它时,它开始工作。如果旧服务器上没有发生这种情况,以及为什么在第 4 次迭代之后发生这种情况,这仍然会留下很多困惑。 @ikegami我不确定系统的返回值是什么,我该如何得到它?我的问题已解决,但我不完全明白为什么感谢您的帮助

标签: perl http ubuntu curl cron


【解决方案1】:

你为什么要掏空来卷曲?如果只是范围,那很容易:

use v5.10.1;

use Mojo::UserAgent;

say Mojo::UserAgent->new->get(
    'http://www.example.com',
    { 'Range' => 'bytes=500-600' }
    )->res->body;

还有与 libcurl 的 Perl 绑定:Net::CurlWWW::Curl

【讨论】:

  • 感谢这个技巧,shell 脚本触发了很多事情(一些由 NOAA 编写的 perl 脚本,它们使用 curl 下载部分 grib 文件。许多其他模块化 shell 脚本也是从这个脚本产生的)。使用 curl 的 perl 脚本是由 NOAA 预先编写的,我还没有时间真正研究它们是如何编写的。 cpc.ncep.noaa.gov/products/wesley/get_gfs.html
猜你喜欢
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多