gpt4 book ai didi

Perl:从 'system' 命令捕获正确的返回值

转载 作者:行者123 更新时间:2023-12-04 18:12:36 27 4
gpt4 key购买 nike

我是 Perl 的初学者。我有一个包含多个 NMake 命令的 Windows 批处理脚本。此批处理脚本的一个现有问题是,即使 NMake 命令在其执行期间失败,ERRORLEVEL没有正确设置。

因此,在我们解析日志文件之前,我们永远不知道该命令是否有效。我调查了它,但找不到解决方案。我,然后考虑将此批处理脚本转换为 Perl 脚本,假设捕获错误会更容易,但似乎并不那么容易:)

每当我运行我的 Perl 脚本时,'system' 命令总是返回 0。我查看了许多不同的链接,并意识到捕获 'system' 命令的正确返回状态并不是那么简单。不过,我尝试了这些建议,但事情没有奏效。 :(

让我提一下,被调用的 NMake 命令在执行过程中又调用了许多不同的命令。例如,下面提到的抛出“ fatal error ”的命令输出实际上是 Perl 脚本 (check_dir.pl) 的一部分。这个对 Perl 脚本的调用是写在 NMake 文件本身中的。

如果我直接调用这个 Perl 文件( check_dir.pl )并检查退出值,我会得到正确的结果,即命令失败并打印一个非零退出值(......意外返回的退出值 2)。

尝试了 Perl 的系统功能,但没有帮助。我使用了以下代码:

system ("nmake /f _nt.mak pack_cd SUB_PLAT=$PLAT DR=$plat 2>&1");

if ( $? == -1 ) {
print "Command failed to execute: $!\n";
}
elsif ( $? & 127 ) {
printf "The child died with signal %d, %s a coredump\n",
( $? & 127 ), ( $? & 128 ) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}

输出:
.....  .....  Unable to open dir: R:\TSM_Latest  Compressing...NMAKE : fatal error U1077: 'if' : return code '0x2'  Stop.  child exited with value 0

Also tried:

use IPC::System::Simple qw(system);  
my $exit_status = system ("nmake /f _nt.mak pack_cd SUB_PLAT=$PLAT DR=$plat 2>&1");

if ($exit_status != 0) {
print "Failure";
exit 3;
} else {
print "Success";
}

最后尝试了以下模块:
use IPC::Run qw( run timeout );  
run "nmake /f _nt.mak pack_cd SUB_PLAT=$PLAT DR=$plat 2>&1" or die "NMake returned $?";

似乎没有任何工作:(

如果我在解释 system 的返回值,请纠正我不正确。

最佳答案

你有:

use IPC::System::Simple qw(system);
my $exit_status = system ("nmake /f _nt.mak pack_cd SUB_PLAT=$PLAT DR=$plat 2>&1");

鉴于您似乎并不关心实际输出,您可以尝试
my $exit_status = systemx(nmake => 
qw(/f _nt.mak pack_cd),
"SUB_PLAT=$PLAT",
"DR=$plat",
);

确保您绕过 cmd.exe看看你是否得到了有用的东西。

作为引用, exit codes from nmake are listed here .

运行以下程序:
use strict; use warnings;

use IPC::System::Simple qw(systemx);
use Try::Tiny;

my $status = 0;

try { systemx nmake => qw(/f bogus) }
catch { ($status) = ( /exit value ([0-9])/ ) };

print "Failed to execute nmake. Exit status = $status\n";

产生:
NMAKE : fatal error U1052: file 'bogus' not foundStop.Failed to execute nmake. Exit status = 2

The following version:

use strict; use warnings;

my $status = system nmake => qw(/f bogus);

if ($status) {
if ($? == -1) {
print "failed to execute: $!\n";
}
elsif ($? & 127) {
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}
}

产生:
NMAKE : fatal error U1052: file 'bogus' not foundStop.child exited with value 2

In fact, even when I use

my $status = system "nmake /f bogus";

我得到了相同的正确和预期的输出。

当我使用时同上
my $status = system "nmake /f bogus 2>&1";

这些观察使我想到以下问题:
  • 你用的是哪个版本的nmake?
  • /I选项有效吗?即使您没有从命令行设置它,note the following :

  • /I Ignores exit codes from all commands. To set or clear /I for part of a makefile, use !CMDSWITCHES. To ignore exit codes for part of a makefile, use a dash () command modifier or .IGNORE. Overrides /K if both are specified.



    所以,我整理了以下文件:
    C:\temp> cat test.maktest.target: bogus.pl; perl bogus.pl
    C:\temp> cat bogus.plexit 1;

    And, ran:

    use strict; use warnings;

    my $status = system "nmake /f test.mak 2>&1";

    if ($status) {
    if ($? == -1) {
    print "failed to execute: $!\n";
    }
    elsif ($? & 127) {
    printf "child died with signal %d, %s coredump\n",
    ($? & 127), ($? & 128) ? 'with' : 'without';
    }
    else {
    printf "child exited with value %d\n", $? >> 8;
    }
    }

    这给了我输出:

    perl bogus.pl
    NMAKE: fatal error U1077:'c:\opt\perl\bin\perl.EXE':返回代码 '0x1'
    停止。
    child 以值 2 退出

    最后一行显示 nmake 的退出状态已正确传播。

    结论:

    你还有其他问题。

    事实上,OP后来在评论中指出:

    The actual command that i am trying to run is: system ("nmake /f _nt.mak pack_cd SUB_PLAT=$PLAT DR=$plat 2>&1 | C:\\tee2 $TEMP_DIR\\modules-nt_${platlogfile}");



    给定 tee参与管道,这并不奇怪 nmake退出代码丢失。 tee能够成功处理 nmake 的输出,所以它返回成功,这就是你的脚本看到的退出代码。

    因此,解决方案是捕获 nmake 的输出。您自己,或者使用 qx (加上适当级别的错误检查),或使用 capture来自 IPC::System::Simple .然后,您可以决定是否要打印该输出、保存到文件、将其放入电子邮件等......

    关于Perl:从 'system' 命令捕获正确的返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10457086/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com