Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Re: accessing an environment variable dynamically

by BrowserUk (Pope)
on Jan 01, 2013 at 20:49 UTC ( #1011182=note: print w/replies, xml ) Need Help??

in reply to accessing an environment variable dynamically

The errorlevel environment variable is set to the return value from programs and scripts run by the command shell (cmd.exe). It is set by the shell.

When you run a program from within Perl using system, there is often no command shell involved, so that environment variable does not get set.

But, you don't need errorlevel to be set, because when you use system, you can access the return code from the program by inspecting the $? variable:

system( q[ perl -E"exit 1;" ] ); print $? >> 8;; 1 system( q[ perl -E"exit 2;" ] ); print $? >> 8;; 2 system( q[ perl -E"exit 3;" ] ); print $? >> 8;; 3 system( q[ perl -E"exit 123;" ] ); print $? >> 8;; 123

There are caveats with this mechanism though. Some are universal, and some windows specific.

  1. Signed versus unsigned exit codes:

    When you extract the return value from $? this way, negative exit codes are return as positive values:

    system( q[ perl -E"exit -123;" ] ); print $? >> 8;; 133 system( q[ perl -E"exit -2;" ] ); print $? >> 8;; 254 system( q[ perl -E"exit -127;" ] ); print $? >> 8;; 129 system( q[ perl -E"exit -128;" ] ); print $? >> 8;; 128 system( q[ perl -E"exit -129;" ] ); print $? >> 8;; 127

    And things get really weird with an exit code of -1:

    system( q[ perl -E"exit -1;" ] ); print $? >> 8;; Can't spawn " perl -E"exit -1;" ": No error at (eval 26) line 1, <STDI +N> line 19. 255
  2. >
  3. Values greater than 255:

    Windows programs can return 32-bit exit codes; but perl sticks slavishly to only handling the 8-bit error codes defined by *nix circa. 1970, which means that under windows, the other 24-bits are discarded:

    system( q[ perl -E"exit 12345;" ] ); print $? >> 8;; 57 system( q[ perl -E"exit 123456789;" ] ); print $? >> 8;; 21

There is a further caveat with system as currently implemented. If the command or program you are running cannot be found, or if the perl internals decide according to some undocumented syntax inspection that you are using "shell characters" in your command; then the program you are invoking will not be run directly by Perl, but rather a copy of cmd.exe will be run and your command will be passed to it to run.

The problem with this is that the exit code that is returned in $? is then not the exit code from your command, but rather the exit code return by cmd.exe; which in most cases will tell you nothing about the success or failure of your command.

Now, when perl invokes the shell to run your command, it will set the exit from your command into the errorlevel environment variable. But it will be its copy of the environment, and by the time control returns to your perl script, that command shell and its copy of the environment will have been discarded, and the exit code from your command will no longer be accessible anywhere.

The bottom line is that the errorlevel environment variable is never useful to you from with your perl script.

With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1011182]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2018-05-21 03:58 GMT
Find Nodes?
    Voting Booth?