2

So I have a program that may or may not segfault (./segf) that also writes other data to stderr. When the program segfaults, its return code is 139 (i.e. echo $? will print 139).

I would like to redirect stderr to /dev/null so as to avoid printing it, however doing so (./segf 2>1) causes the return code to be set to 1. Now it's impossible to differentiate whether the program is truly segfaulting or just returning an error.

Is it possible to pipe stderr's other errors while still being able to check that the return code would be 139?

./segf >/dev/null; echo $? results in 139

./segf >/dev/null 2>1; echo $? results in 1

bash -c './segf' results in 139

bash -c './segf' 2>1 results in 1

  • 2
    ./segf >/dev/null 2>1 will redirect the stderr to a file called 1. Is that really what you ran? – terdon Jun 5 at 12:42
  • Doing 2>1 you write the standard error to the file with name "1". The 2>&1 should be used. whats difference between 2>1 > /dev/null and 2>&1 >/dev/null – MiniMax Jun 5 at 12:43
  • 2
    Why does having stderr go to /dev/null cause the program not to segfault? Based on your description it appears that the program is going out of its way to work differently depending on where stderr is going to. In that case by definition the answer to your question is no, if stderr is redirected then you don't get a segfault, so the return code doesn't indicate you did. – icarus Jun 5 at 12:47
  • @terdon Yes, 2>1 goes to a file called 1, however changing it to 2>&1 doesn't affect the main issue with return code being altered due to redirection. – jbal Jun 5 at 13:19
  • @jbal where is &1 being sent to when you do that? Are you trying to write to a file you don't have access to? What does ./segf 2>&1; echo $? return? – terdon Jun 5 at 13:22
1

None of the things you tried should affect the exit status. You can test with this very simple script:

#!/bin/sh
echo out
echo err >&2
exit 139

Now execute it with the various redirects:

$ foo.sh; echo $?
out
err
139

#redirect stdout to /dev/null and stderr to a file called '1'
$ foo.sh >/dev/null 2>1; echo $?
139

## Redirect stderr to /dev/null
$ foo.sh 2>/dev/null; echo $? 
out
139

The way to redirect a command's stderr is just command 2>/dev/null, but that should never affect the command's exit status, unless the redirection fails. This is actually what probably happened in your case. If you don't have write permissions in the directory where you are and you tried to run ./segf >/dev/null 2>1 (instead of ./segf >/dev/null 2>&1), that would have attempted to create a file called 1 to redirect stderr to. If the file can't be created, you would get an exit status of 1:

$ foo.sh 2>1; echo $? 
bash: 1: Permission denied
1
  • Note that segfaulting (or, more generally, being killed by a signal) is different from exiting with a return code >128. Can you still reproduce this with kill -SEGV $$ or similar? (Sorry, typing from phone, can't check myself.) I'm also skeptical of the claim, just pointing out your reproducer might not be close enough to the OP's. – filbranden Jun 5 at 12:54
  • 1
    @filbranden yes, that's a fair point, but no matter how it is killed, redirection should never affect the exit status. And I can't test with kill -SEGV $$ since if file 1 isn't writeable, the script will exit immediately as soon as it attempts to write to stderr. The issue is almost certainly that the OP was trying to write to file that wasn't writeable, so the shell was killing the process long before the segfault was ever reached. – terdon Jun 5 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.