Perl系统调用失败,返回代码为65280。

4

我运行了下面的Perl代码。

$retCode = ClearCase($cmd); 

代码没有错误,但是当我运行下面的代码时,它会返回 65280

$retCode = ClearCase($logcmd); 

我在XP和Windows 2003服务器上尝试了一下,结果相同,都是使用ActiveState Perl v5.14.2。

这段代码两年前在其他地方可以运行。

  $g_HPPC_DEV_DRIVE =  "M";
  $g_HPPC_DEV_VIEW = "bldforge_AOMS_DEV";
  $g_logfile = "logfile.txt";
  
  $cmd = "startview $g_HPPC_DEV_VIEW";
  $logcmd = $cmd . " >> $g_logfile 2>>&1";
  
  $targetDir = $g_HPPC_DEV_DRIVE . ":\\" . $g_HPPC_DEV_VIEW;
  print "\$targetDir = $targetDir\n"; 
  print "Starting view .......\n"; 
  #$retCode = system("cleartool startview bldforge_AOMS_DEV >> logfile.txt");
  #$retCode = `cleartool startview bldforge_AOMS_DEV`;

  $retCode = ClearCase($logcmd);
  #$retCode = ClearCase($cmd);

sub ClearCase
{
  my $retCode = 0;
  my $args = $_[0];

  my $cmd = "cleartool " . $args;
  $retCode = Execute($cmd);

  return $retCode;

}

sub Execute
{
  my $retCode = 0;
  my $cmd = $_[0];

  if ($g_HPPC_BUILD_SIMULATION ne "Y")
  {
     
     print("Execute() Running...:   $cmd\n");     
     $retCode = system($cmd);
     #$retOut = `$cmd`;     
     #$retCode = $?;
     #print("Command execute output: $retOut\n");
  }
  else
  {
     print("Execute() *** SIMULATION:   $cmd\n");     
  }

  print("Execute() retCode = $retCode, $cmd\n");
  
  return $retCode;
}

这个65280退出代码是什么意思?

你应该使用 autodie 或检查 $! 来查看是否有更详细的信息。不过,很可能是由于某种原因导致 "clearcase" 出现了问题,所以你需要从那里开始调查,而不是从你的 Perl 代码开始。 - zostay
为了使system也能致命化,必须使用use autodie qw(:all) - daxim
重定向运算符2>>&1看起来很奇怪,尝试使用单个楔形符号2>&1 - tripleee
和2>&1一样。这段代码在另一个环境中都是正常工作的。不知道为什么在这里不起作用。 - Alex
退出码65280是一个无效的Unix退出码。正确的范围是7位:0-255。我从Linux上的bash 5.0.18 shell调用python3.8.5运行exit_code = os.system("ssh user@host_ip 'some_command.sh'")时,收到了65280的退出码。这个命令需要超过5分钟,并且我强制停止了sshd服务器端、拔掉了电脑、拔掉了无线路由器或者其他TCP的快速崩溃。Python客户端没有从操作系统接收到任何数据,Python将一个64位整数压缩成7位:65280。这个数字非常接近于最大的16位值65536,因此有些可疑。 - Eric Leschinski
2个回答

6
请记住,正如在perldoc -f system中所记录的那样,system的返回值“...是由wait调用返回的程序的退出状态。要获取实际的退出值,请右移八位...”。将65280右移8位得到255。
但不幸的是,这也不是非常有用,因为据我所知,每个可能的cleartool退出代码的确切含义都没有记录。我能找到最接近的是cleartool文档中的此链接,在其中它声明,“单命令模式下的退出状态取决于命令是否成功(零退出状态)或生成错误消息(非零退出状态)。”
所以你现在知道了;255是一个非零的退出状态,表示出现了错误条件。好的一面是,也许它正在生成一个错误消息,只是你没有看到。
作为解决问题的技巧,既然你已经打印了$cmd,从命令行调用与你的程序生成的相同命令的cleartool。如果你得到相同的结果,问题就变成了一个cleartool问题,而不是一个Perl问题。而且幸运的是,这个错误条件将生成一个错误消息,你可以看到而不仅仅是一个退出代码。
另一方面,如果你得到了正确的行为,请开始查看Perl运行时环境与命令行环境之间的区别;权限、环境变量、路径、工作目录等。

问题仍然存在:我可以运行 $retCode = ClearCase($cmd); 没有错误,但是当运行 $retCode = ClearCase($logcmd); 时返回 65280。这个 " >> $g_logfile 2>>&1" 导致了问题。我也可以在 Windows 命令行中无问题地运行。我无法使用 system() 或 `` 调用获取任何错误消息。不知道它失败的原因。 - Alex
@Alex 如果你的解释器编程语言将默认的16位或64位数字填充到7位Unix数字中,那么这个损坏的内存会以65280的形式被终端反馈给你。这是无论什么程序产生该数字的失败致命错误恢复尝试。 - Eric Leschinski

3
使用cleartool时,最好确保使用ClearCase附带的Perl包ccperl现在称为ratlperl),而不是最新的Active Perl实际上是5.14.2版本)。因此,不要默认启动您的Perl脚本,选择在%PATH%中找到的第一个perl.exe,而是尝试使用ClearCase附带的一个Perl版本进行调用:
  • ratlperl:位于C:\Program Files\Rational\Common
  • 或者传统的ccperl:位于C:\Program Files\Rational\ClearCase\bin
然后看看错误是否仍然存在。
根本原因是“PATH”问题:有多个可用的“perl”:
  • 来自Rational ClearCase的“perl”
  • 来自Active Perl的“perl”
通过确保“PATH”只引用一个“perl”(即ClearCase附带的那个),可以成功启动脚本。

当我使用ccperl或ratlperl时,出现了这个错误。里面有注册表代码,如何更新版本?Win32 :: Registry对象版本0.07与$ Win32 :: Registry :: VERSION 0.10不匹配,在C:/ Program File中的IBM / RationalSDLC / common / lib / perl5 / 5.8.6 / MSWin32-x86-multi-thread / DynaLoader.pm第253行。 编译失败,需要在Z:// .. / common.pl第12行。 BEGIN失败 - 在Z:// .. / common.pl第12行中中止编译。 在build.pl第28行中需要编译。 - Alex
@user1288329 http://www-01.ibm.com/support/docview.wss?uid=swg21289331: "问题可能是由于在同一系统上安装了多个版本的Perl,并且搜索路径环境变量设置为首先选择“不正确”的Perl版本而引起的。" 确保您的PATH不包含任何其他Perl。 - VonC
删除多个Perl路径解决了问题。非常感谢! - Alex
好的,已经发布在这里了。https://dev59.com/j2fWa4cB1Zd3GeqPgmQu\ 我已经接受了答案。这是我第一次在这里发问题。看起来这个地方可以发布任何类型的问题? - Alex
@user1288329 很好,我已经在那里发布了一个答案。 - VonC
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接