Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

capturing stderr of echo piped to a file

by cebundy (Novice)
on Oct 28, 2014 at 19:10 UTC ( [id://1105354]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to issue this command via perl, and capture the std error:
my $file = "/mnt/adtest/qa1/file1"; my $writeline = "# $test->{currentuser} wrote timestamp " . time() +; my $command = "echo $writeline >> $file"; my $output = `$command 2>&1`;
This is a part of a test where I am looking for an error (specifically "permission denied"). However $output is always empty. When I run from the linux command line I do see the output. I suspect that the stderr output is lost in redirection when run via perl. Anyone know how to get around this?
[root@qanode1-2 latest]# echo "qauser1 wrote timestamp 1414118740-1" > +> /mnt/adtest/qa1/file1 -bash: /mnt/adtest/qa1/file1: Permission denied

Replies are listed 'Best First'.
Re: capturing stderr of echo piped to a file
by Anonymous Monk on Oct 28, 2014 at 19:35 UTC
    use system with use Capture::Tiny
    use Capture::Tiny qw/ capture /; my($stdout, $stderr, $exit) = capture { system { $args[0] } @args; };;
      Thanks. I was hoping for something a little simpler in the sense of not having to install and load another module, but this works, which is the important thing.
Re: capturing stderr of echo piped to a file
by Crackers2 (Parson) on Oct 28, 2014 at 22:10 UTC

    Your redirection is in the wrong order:

    my $command = "echo $writeline >> $file"; my $output = `$command 2>&1`;

    Writing that out, you end up with

    my $output = `$command echo $writeline >> $file 2>&1`;

    Which means redirect STDOUT to the file, then STDERR to (current) STDOUT, i.e. also to the file. You probably want

    my $output = `$command echo $writeline 2>&1 >> $file`;

    instead, i.e. redirect STDERR to STDOUT, then STDOUT (but not the redirected STDERR) to the file.

      Your statement is simply not true. The order of the redirects doesn't matter and in my experience having 2>&1 at the end of the line is much more common. A simple test on the command line with a perl script that issues a warn as well as a print statement will demonstrate this.

      You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

        Perhaps you should just try it?

        > { echo out; echo err >&2; } >f1 2>&1 > cat f1 out err > { echo out; echo err >&2; } 2>&1 >f1 err > cat f1 out

        Redirection order definitely DOES matter in the shell. (Hmm, unless it's shell-specific? I'm using bash)

        And just to do exactly what you said..

        > perl -e'print "print\n"; warn "warn"' >f1 2>&1 > cat f1 warn at -e line 1. print > perl -e'print "print\n"; warn "warn"' 2>&1 >f1 warn at -e line 1. > cat f1 print

        In the first case both print and warn go to the file, in the second case warn goes to stdout and print to the file.

Re: capturing stderr of echo piped to a file
by boftx (Deacon) on Oct 29, 2014 at 18:55 UTC

    Here is how I've done it in test files:

    # Capture any STDERR output my $stderr = ''; local *STDERR; open STDERR, '>', \$stderr;
    I can't remember where I first saw that, but I've kept it handy ever since.

    You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
      That isn't as portable/reliable as Capture::Tiny, there are many such modules ... Capture::Tiny got created pretty late in the game but its the best of the best

        Agreed. I was simply showing a way to do it that I found handy back before then in response to the stated desire to avoid extra modules. I'm not even sure it would work in the situation given, but might be worth looking at.

        You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2024-03-28 12:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found