Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

qx and STDERR?

by morgon (Priest)
on Nov 25, 2019 at 19:24 UTC ( [id://11109195]=perlquestion: print w/replies, xml ) Need Help??

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

Hi

is there a way to capture the output of an external program that writes to stderr with qx?

I thought I'd simply redirect stderr, but it's not so simple, eg:

print qx(ffmpg -f s16le -i out.raw 2>&1);
does not capture the output of the ffmpeg-command.

I am aware that there are other ways to capture stderr, this is a specific qx question.

Many thanks!

Replies are listed 'Best First'.
Re: qx and STDERR?
by Fletch (Bishop) on Nov 25, 2019 at 19:32 UTC

    If you've redirected things you should be getting the STDERR output as well.

    $ perl -E '$foo = qx{zsh -c "print I GO TO OUT; print I GO TO ERR 1>&2 +" 2>&1}; say qq{foo: |$foo|}' foo: |I GO TO OUT I GO TO ERR |

    My suspicion is that the output may be explicitly going to the tty instead of STDERR so redirection this way isn't going to affect it.

    Update: Well nope, that's not it. Seems to capture things fine for me (OS X, perl 5.18.2, homebrew'd ffmpeg 4.2.1).

    $ perl -E '$foo = qx{ffmpeg -f s16le -i /dev/null 2>&1}; say qq{foo: | +$foo|}' foo: |ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg develope +rs built with Apple LLVM version 10.0.0 (clang-1000.11.45.5) configuration: --prefix=/Users/fletch/lib/homebrew/Cellar/ffmpeg/4.2 +.1_2 --enable-shared --enable-pthreads --enable-version3 --enable-avr +esample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines +/jdk1.8.0_221.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMa +chines/jdk1.8.0_221.jdk/Contents/Home/include/darwin' --host-ldflags= + --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enabl +e-libbluray --enable-libmp3lame --enable-libopus --enable-librubberba +nd --enable-libsnappy --enable-libtesseract --enable-libtheora --enab +le-libvidstab --enable-libvorbis --enable-libvpx --enable-libx264 --e +nable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig - +-enable-libfreetype --enable-frei0r --enable-libass --enable-libopenc +ore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-li +brtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disa +ble-libjack --disable-indev=jack libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100 Guessed Channel Layout for Input Stream #0.0 : mono Input #0, s16le, from '/dev/null': Duration: N/A, bitrate: 705 kb/s Stream #0:0: Audio: pcm_s16le, 44100 Hz, mono, s16, 705 kb/s At least one output file must be specified |

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: qx and STDERR?
by haukex (Archbishop) on Nov 25, 2019 at 19:34 UTC

    qx// only captures the command's STDOUT, to get STDERR, you'd have to use the redirection you showed, although whether that works will be dependent on the exact system you're running on - see The problem of "the" default shell.

    print qx(ffmpg -f s16le -i out.raw 2>&1); does not capture the output of the ffmpeg-command.

    Unfortunately I can't reproduce that, qx/ffmpeg ... 2>&1/ works for me on my Linux system. You'll have to be more specific about what system you're on, what version of Perl, version of ffmpeg, etc.

    I am aware that there are other ways to capture stderr

    Unless this is a script where you're certain it will only be run on one machine and it doesn't need to be portable, I really, strongly recommend to use one of those alternative ways. I wrote about them here (in short, IPC::Run3 for short-lived subprocesses, and IPC::Run for longer-running ones, in case you need to interact with them, run them in the background, etc.).

      Yeah. The default shell seems to be a likely culprit.

      I am on Debian testing, perl 5.26.1 ffmpeg 4.2.1.

      It's not a big deal, I just would like to understand what is going on...

        I just would like to understand what is going on...

        The versions you named don't seem very exotic, and without being able to reproduce it, I can't tell you more. Is qx(ffmpg -f s16le -i out.raw 2>&1) the actual command you're running (is "ffmpg" a typo)? Because if you're doing any other redirections there, the order makes a difference. Otherwise, I'd suggest debugging with strace and perhaps lsof to get some clues why your redirection isn't working.

Re: qx and STDERR?
by bliako (Monsignor) on Nov 26, 2019 at 08:22 UTC

    There are lots of other options, e.g. System::Command, which let you handle each std stream individually, if you don't have to use qx

    There is also Capture::Tiny which will capture your std streams, from manpage:

    use Capture::Tiny ':all'; my ($stdout, $stderr, $exit) = capture { qx/ls -al file-does-not-exist/ };

    p.s. I leave here just for reference a guide to IO redirection in bash - really cool stuff: http://tldp.org/LDP/abs/html/io-redirection.html

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2024-04-19 03:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found