Perl: getting the correct return value from the 'system' command

I am new to Perl. I have a windows script package that contains several NMake commands. The existing problem with this batch of script is that even if the NMake command does not work during its execution, ERRORLEVELit is not installed properly.

Therefore, we never know whether the team worked until we analyze the log file. I looked into it, but could not find a solution. I then thought about converting this batch of script to a Perl script, assuming the capture error would be simpler, but it doesn't seem to be that simple :)

Whenever I run my Perl script, the "system" command always returns 0. I looked at many different links and realized that grabbing the correct return status for "system" is not so simple. However, I tried the suggestions, but it doesn’t work. :(

Let me mention that the NMake command, which is called, in turn, calls many different commands during its execution. For example, the command output mentioned below, which throws a “fatal error”, is actually part of the Perl script (check_dir.pl). This Perl script call is written in the NMake file itself.

If I call this Perl ( check_dir.pl) file directly and check the exit value, I get the correct result, that is, the command fails and prints a non-zero exit value (... unexpectedly returned exit value 2).

I tried the Perl system function, but that didn't help. I used the following code:

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;
}

Output:

.....  
.....  
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";  
}

Finally, I tried the following module:

use IPC::Run qw( run timeout );  
run "nmake /f _nt.mak pack_cd SUB_PLAT=$PLAT DR=$plat 2>&1" or die "NMake returned $?";

Nothing seems to work :(

Please correct me if I misinterpret the return value system.

+5
source share
1 answer

You have:

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

Given that you don't seem to care about the actual output, you can try

my $exit_status = systemx(nmake => 
                              qw(/f _nt.mak pack_cd),
                              "SUB_PLAT=$PLAT",
                              "DR=$plat",
                          );

To make sure you get around cmd.exeand see that you are getting something useful.

For reference, exit codes from nmake are listed here .

Running the following program:

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";

gives:

NMAKE : fatal error U1052: file 'bogus' not found
Stop.
Failed to execute nmake. Exit status = 2

:

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 found
Stop.
child exited with value 2

,

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

.

,

my $status = system "nmake /f bogus 2>&1";

:

  • nmake ?

  • /I? , :

/I . /I makefile, !CMDSWITCHES. makefile, () .IGNORE. /K, .

, :

C:\temp> cat test.mak
test.target: bogus.pl; perl bogus.pl
C:\temp> cat bogus.pl
exit 1;

, :

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' : return code '0x1'
Stop.
child exited with value 2

, nmake .

:

.

OP , :

, : 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, , script .

, , nmake qx ( ), capture IPC::System::Simple. , , , .. & Hellip;

+7

All Articles