in reply to Re: Using backquotes to echo results in "Bad file descriptor"
in thread Using backquotes to echo results in "Bad file descriptor"

I'm completely fine with not using $! as an error indicator. I also understand that an earlier system/library call could have set it since it doesn't get reset, but you'll notice there are no other commands in my example, so I know that's not the case.

I just did another test using a different shell command (ls) and $! produces the same thing. So my guess is that $! gets set to "Bad file descriptor" whenever you use backquotes that send data to STDOUT. If I redirect to /dev/null $! is empty.

I appreciate the help, but I'm not trying to simply "get my script working", I'm trying to understand why $! gets set. Call it curiosity. I call it OCD. ;)
  • Comment on Re^2: Using backquotes to echo results in "Bad file descriptor"

Replies are listed 'Best First'.
Re^3: Using backquotes to echo results in "Bad file descriptor"
by kennethk (Abbot) on Mar 04, 2009 at 18:48 UTC
    Did you read error indicators? Essentially (as gwadej and toolic as also pointed out) you are not checking the error code you think you are. $! is set by the perl C libraries, not by external system calls, and its value is essentially meaningless unless a Perl library call (like open) just failed. On the other hand $? is set to the return value of the invoked system call, and as such is what you need to check in the case of backticks (or system).
      Yes, I realize now that I'm not doing my error checking correctly by using $! but my next question (read: obsession) is why do the perl C libraries set errno to "Bad file descriptor" whenever perl executes a shell command using backquotes that sends data to STDOUT?

      Consider this:

      perl -e '$res = `echo test`; print $!."\n";'

      versus this:

      perl -e '$res = `echo test>/dev/null`; print $!."\n";'

      In the first example, $! is "Bad file descriptor". In the latter example, $! is empty. So whatever the answer is, it has something to do with whether or not the command has output. You can replace "echo test" with any shell command that produces STDOUT info.

        Try using strace to find out.

        Nevermind, I just did, and I don't see a system call returning that error.

        Not entirely sure, but an interesting test case I found is the following:

        perl -e 'print `echo test`; print $!."\n";'

        shows $! to be empty. I am guessing the issue is that echo is attempting to output to a non-existent terminal, and this error is a result of an internal perl call to determine if the output is being piped to an existing terminal. Note that

        perl -e 'print $res = `echo test`; print $!."\n";'

        does yield $! eq "Bad file descriptor".