http://www.perlmonks.org?node_id=579104

asarih has asked for the wisdom of the Perl Monks concerning the following question:

Consider: perl -e 'qx(date); print "$!"'

On HP-UX and AIX, you get no output. On Linux, you get "Bad file descriptor" and on Solaris, you get "Illegal seek". Could someone enlighten me why?

Replies are listed 'Best First'.
Re: qx and $!
by davorg (Chancellor) on Oct 18, 2006 at 15:35 UTC

    From perldoc perlvar:

    ...if a system or library call fails, it sets this variable. This means that the value of $! is meaningful only immediately after a failure

    As there was no failure, the value of $! is meaningless in your example.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: qx and $!
by liverpole (Monsignor) on Oct 18, 2006 at 15:38 UTC
    Hi asarih,

    If you read perlvar, you'll see about $!:

    If used numerically, yields the current value of the C "errno" variable, or in other words, if a system or library call fails, it sets this variable. This means that the value of $! is meaningful only immediately after a failure:

    For your purposes, the key phrase is "meaningful only immediately after a failure".

    So you're trying to attach meaning to something that isn't useful in this case (ie. the value of errno).

    Update:  Hey, no fair davorg!  You clearly have the perldocs memorized, whereas I had to go look it up; that's why you beat my answer! :)


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      Update: Hey, no fair davorg! You clearly have the perldocs memorized, whereas I had to go look it up; that's why you beat my answer! :)

      It's not fair only if you assume that there's a competition going on, at who answers the first - although I admit I like to be the one myself, on occasions. Otherwise, repetita iuvant. (Latin idiomatic expression which means "repetitions help".) Well, if taken in non excessive doses, cum grano salis...

      Note that a "system call" is not a call of system — or qx! Instead, it's a call of a call of an OS implemented function.

      Errors on those command lines usually send their error messages to STDERR, and also may set "errorlevel" (as it's known in DOS), aka the last program's exit code, which you can read through $? (child error) after some calculation.

Re: qx and $!
by cdarke (Prior) on Oct 18, 2006 at 15:46 UTC
    $! is not necessarily an error. Sometimes code will try something and if it didn't work try something else. Loading executable files from different directories in a path is an example. You should test the return value from a function to see if it gave an error, not $!. If you want the return value from a child process then it's $? you need.
Re: qx and $!
by jkva (Chaplain) on Oct 19, 2006 at 13:07 UTC
    I don't have anything useful to add, except that it's awesome to have access to so many different *NIXes :)
Re: qx and $!
by Bro. Doug (Monk) on Oct 19, 2006 at 02:46 UTC
    On a Mac, it prints nothing.

    However, if you change this to:
    perl -e 'print qx(date);'
    ... you'll get the date printed on the command line.

    qx executes the system's date command and returns it as a quoted string. $! refers to the last error thrown by a statement that isn't in an eval block.

    Why it's a 'Bad file descriptor' or 'Illegal seek' is interesting. I don't know. I suspect, however, that this is what you really wanted to know when you posed this question. (?)

    At any rate... I'd like to know. I'll test it tomorrow on a Linux system, since my Mac doesn't seem to freak out on an unset $!.
    Bro. Doug :wq
      Some operations set $! to 0 on success (but don't count on it!). "Bad file descriptor" is error 0 on some systems.
      $! = 0; print("$!\n"); # Bad file descriptor, or Illegal seek, or ...
      Fellow monks,

      I promised this update about a week ago or more, but forgot. For this failure, I deeply apologize.

      However, I did the testing I promised.

      The findings are rather interesting. On a Linux system, $! only returns a 'Bad File Descriptor' message when called immediately after qx(). I tried calling $! empty, and it returned nothing.

      Perhaps someone knows how the $! is tied to the handle used to return info from qx() ?

      Peace be you, monks.
      Bro. Doug :wq
Re: qx and $!
by helgi (Hermit) on Oct 20, 2006 at 11:10 UTC
    A comparison on how to run external programs and get meaningful errors from them:
    print qx(date) or die "Cannot run date:$!\n"; system (date) == 0 or die "Cannot run date:$?\n";

    --
    Regards,
    Helgi Briem
    hbriem AT f-prot DOT com

      That's not right.

      • Both qx and system set $! when unable to launch the child.
      • Both qx and system set $? to the child's error code.
      • An error did not necessarily occur when qx return false, only when it returns undef.
      • $! is not necessarily set when qx return false, only when it returns undef.

      Here is how one actually gets meaningful errors from them:

      my $output = qx(date); die("Unable to launch external process: $!\n") if not defined $output; die("The external process did not run successfully (error code $?)\n") if $?;
      my $rv = system(date); die("Unable to launch external process: $!\n") if $rv == -1; die("The external process did not run successfully (error code $?)\n") if $?;