http://qs321.pair.com?node_id=11120245


in reply to Effect of redirecting output to /dev/null on $? value

`$cmd` usually involves running /bin/sh with -c and the value of $cmd as arguments.

The use of the shell is optimized away if the command is simple enough. That is apparently the case in the first snippet.

In the second snippet, you are getting the exit status of /bin/sh. It returns 0x80 | signal_num when the program it runs is killed by a signal.

You could use the following to execute the program in the child process instead of creating a grandchild:

`exec my_executable_that_seg_faults >/dev/null`;

And you can avoid the shell entirely using IPC::Run.

Update: Added exec (before I noticed jcb mentioning it).

Replies are listed 'Best First'.
Re^2: Effect of redirecting output to /dev/null on $? value
by Special_K (Monk) on Aug 03, 2020 at 06:35 UTC

    Thanks for the explanation. I ran a different, more complex application with a deliberate seg fault added again using my method above and now see the following as the output:

    sh: line 1: 26902 Segmentation fault my_complex_executable_that_s +egfaults > /dev/null return value is 35584 exit_value = 139 signal_num = 0 dumped_core = 0
    In the above case, 0x80 | signal_num = 0x80 | 0x0B = 0x8B = 139, which matches the listed exit_value. 35584 is just the exit value shifted up 8 bits, which is consistent with the definition of $?.

    What does the 26902 value indicate? Is that the 16-bit status int set by wait(2) from running my_complex_executable_that_segfaults that can be parsed by perl to assemble the fields of the $? variable, and can also be accessed directly in C/C++ using the macros WTERMSIG, WEXITSTATUS, etc. (source: https://linux.die.net/man/2/wait)?

      What does the 26902 value indicate?

      The shell generated that message to report that a subprocess with PID 26902 exited with a segmentation fault. The hint is that it starts with "sh: line 1:". The shell sees your command as a one-line shell script.

      What does the 26902 value indicate?

      pid? I don't think I've ever seen a message like that.

      It's not a exit status. 26902 = 0x6916. As a status, this would mean the process exited with code 0x69 and it was killed by signal 0x16, but those are mutually exclusive.

Re^2: Effect of redirecting output to /dev/null on $? value
by Special_K (Monk) on Aug 03, 2020 at 15:34 UTC
    How is the command executed if the shell is not invoked?
    Why does adding a redirect to /dev/null increase the complexity enough to invoke the shell?
    Finally, what method is used to execute the command if I had instead used perl's system() function instead of the backticks?

      This is pretty much all covered in the docs for system().

      Why does adding a redirect to /dev/null increase the complexity enough to invoke the shell?

      Because it's the shell that does the redirection.


      🦛

      How is the command executed if the shell is not invoked?

      By asking to system execute the specified program instead of asking the system to execute /bin/sh.

      Why does adding a redirect to /dev/null increase the complexity enough to invoke the shell?

      There's no point in including an entire shell in Perl. I don't know exactly what part of shell command parsing is implemented in Perl.

      Finally, what method is used to execute the command if I had instead used perl's system() function instead of the backticks?

      system($cmd), exec($cmd), open(my $pipe, '-|', $cmd) (and its 2-arg form) and open(my $pipe, '|-', $cmd) (and its 2-arg form) work the same way as `$cmd` (aka qx`$cmd` aka readpipe($cmd)).

      system($prog, LIST) where LIST returns at least one scalar won't invoke the shell.[1]

      system({ $prog } $prog, LIST) won't invoke the shell.


      1. It can in Windows.