Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

if (STDERR == STDOUT)

by freja (Initiate)
on Mar 06, 2007 at 16:23 UTC ( #603447=perlquestion: print w/replies, xml ) Need Help??

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

Hi,

it might be a silly question.. I have a Perl script:

print STDOUT 'This is an important message!'; print STDERR 'This is an important message!';

So, I want to be sure that the text appears in both stdout and stderr files. But if a user run the script as

./my.pl >log 2>&1
the message is repeated... Is any way to check that both streams are connected to the same file?

Replies are listed 'Best First'.
Re: if (STDERR == STDOUT)
by merlyn (Sage) on Mar 06, 2007 at 16:35 UTC
    Untested, but I've written something similar before:
    sub dev_ino_of_handle { join " ", (stat shift)[0, 1] } sub send_maybe_both { my $text = shift; print STDOUT $text; print STDERR $text unless dev_ino_of_handle(\*STDOUT) eq dev_ino_of_ +handle(\*STDERR); } ... send_maybe_both("HEY!\n");
Re: if (STDERR == STDOUT)
by imp (Priest) on Mar 06, 2007 at 16:39 UTC
    I second ikegami's advice - you should handle this with a commandline option instead of trying to detect whether the file descriptor for STDOUT and STDERR are writing to the same stream. From perl's perspective they are separate entities, as can be seen with fileno.

    As a last resort you could query the operating system with tools like lsof or the proc filesystem to find out where that filedescriptor is writing... but that would be somewhat bad mojo and should be avoided.

Re: if (STDERR == STDOUT)
by ikegami (Patriarch) on Mar 06, 2007 at 16:28 UTC
    This might be something that's best done through command-line options.
      Just to expand on ikegami's command line option suggestion (which I agree with), you may want to check out the command's tee or mkfifo. Either one of these 2 will be able to push text to more than one file (or pipe).
Re: if (STDERR == STDOUT)
by Rhandom (Curate) on Mar 06, 2007 at 16:36 UTC
    If all you have is the end of a pipe - it is hard to say what is on the other side. You could try and fish around in /proc/$$/fd . You could look at the 1 and 2 files to see if they are to the same thing.
    paul@paul-laptop:~/$ perl -e 'print "Pid: $$\n"; print `ls -l /proc/$$ +/fd`' Pid: 391 total 8 lrwx------ 1 paul paul 64 2007-03-06 09:34 0 -> /dev/pts/1 lrwx------ 1 paul paul 64 2007-03-06 09:34 1 -> /dev/pts/1 lrwx------ 1 paul paul 64 2007-03-06 09:34 2 -> /dev/pts/1 lr-x------ 1 paul paul 64 2007-03-06 09:34 3 -> pipe:[162460] l-wx------ 1 paul paul 64 2007-03-06 09:34 4 -> pipe:[162460] lr-x------ 1 paul paul 64 2007-03-06 09:34 5 -> pipe:[162461] lr-x------ 1 paul paul 64 2007-03-06 09:34 6 -> inotify l-wx------ 1 paul paul 64 2007-03-06 09:34 7 -> pipe:[162461] paul@paul-laptop:~/$ perl -e 'print "Pid: $$\n"; print `ls -l /proc/$$ +/fd`' 2>&1 Pid: 393 total 5 lrwx------ 1 paul paul 64 2007-03-06 09:34 0 -> /dev/pts/1 lrwx------ 1 paul paul 64 2007-03-06 09:34 1 -> /dev/pts/1 lrwx------ 1 paul paul 64 2007-03-06 09:34 2 -> /dev/pts/1 lr-x------ 1 paul paul 64 2007-03-06 09:34 3 -> pipe:[162483] lr-x------ 1 paul paul 64 2007-03-06 09:34 6 -> inotify paul@paul-laptop:~/$ perl -e 'print "Pid: $$\n"; print `ls -l /proc/$$ +/fd`' 2>/dev/null Pid: 395 total 8 lrwx------ 1 paul paul 64 2007-03-06 09:34 0 -> /dev/pts/1 lrwx------ 1 paul paul 64 2007-03-06 09:34 1 -> /dev/pts/1 l-wx------ 1 paul paul 64 2007-03-06 09:34 2 -> /dev/null lr-x------ 1 paul paul 64 2007-03-06 09:34 3 -> pipe:[162501] l-wx------ 1 paul paul 64 2007-03-06 09:34 4 -> pipe:[162501] lr-x------ 1 paul paul 64 2007-03-06 09:34 5 -> pipe:[162502] lr-x------ 1 paul paul 64 2007-03-06 09:34 6 -> inotify l-wx------ 1 paul paul 64 2007-03-06 09:34 7 -> pipe:[162502]


    my @a=qw(random brilliant braindead); print $a[rand(@a)];
Re: if (STDERR == STDOUT)
by Moron (Curate) on Mar 06, 2007 at 18:02 UTC
    At the beginning of your script you could close and then re-open both for shared update (which will fail if not redirected to a file), if that succeeds for both channels, print a one byte token to both channels, seek back to 0, reread and check for duplicates, flag the findings, seek both back to 0 again and then continue normally, which will overwrite the token from top. For whichever channel it fails on, open it again for normal output.

    -M

    Free your mind

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://603447]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (2)
As of 2022-12-03 16:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?