Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to I print to STDERR only if STDOUT is a different destination?

I would like Perl to write to STDERR only if STDOUT is not the same. For example, if both STDOUT and STDERR would redirect output to the Terminal, then I don't want STDERR to be printed.

Consider the following example (outerr.pl):

#!/usr/bin/perl

use strict;
use warnings;

print STDOUT "Hello standard output!\n";
print STDERR "Hello standard error\n" if ($someMagicalFlag);
exit 0

Now consider this (this is what I would like to achieve):

bash $ outerr.pl
Hello standard output!

However, if I redirect out to a file, I'd like to get:

bash $ outerr.pl > /dev/null
Hello standard error

and similary the other way round:

bash $ outerr.pl 2> /dev/null
Hello standard output!

If I re-direct both out/err to the same file, then only out should be displayed:

bash $ outerr.pl > foo.txt 2>&1
bash $ cat foo.txt
Hello standard output!

So is there a way to evaluate / determine whether OUT and ERR and are pointing to the same “thing” (descriptor?)?

like image 990
h q Avatar asked Mar 14 '13 18:03

h q


People also ask

How would you redirect a command stderr to STDOUT?

The regular output is sent to Standard Out (STDOUT) and the error messages are sent to Standard Error (STDERR). When you redirect console output using the > symbol, you are only redirecting STDOUT. In order to redirect STDERR, you have to specify 2> for the redirection symbol.

When can I print to stderr?

It is good practice to redirect all error messages to stderr , while directing regular output to stdout . It is beneficial to do this because anything written to stderr is not buffered, i.e., it is immediately written to the screen so that the user can be warned immediately.

Why do we have both STDOUT and stderr as ways of printing to the screen?

These three special file descriptors handle the input and output from your script or a process. while STDIN or Standard Input helps the Linux Process or a script to get its input from the user ( typing in the keyboard) the Standard output STDOUT and Error STDERR helps to display the result to the user on the monitor.


1 Answers

On Unix-style systems, you should be able to do:

my @stat_err = stat STDERR;
my @stat_out = stat STDOUT;

my $stderr_is_not_stdout = (($stat_err[0] != $stat_out[0]) ||
                            ($stat_err[1] != $stat_out[1]));

But that won't work on Windows, which doesn't have real inode numbers. It gives both false positives (thinks they're different when they aren't) and false negatives (thinks they're the same when they aren't).

like image 149
cjm Avatar answered Nov 08 '22 08:11

cjm