Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

qx and STDERR?

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

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


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:

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (4)
As of 2023-03-22 09:49 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (60 votes). Check out past polls.