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

I would like to start a system command from a Perl script, but let it be an interactive bash session. Either in the same terminal window, or in a new window.

In this case, the process I want to start from Perl is an ffmpeg conversion. That can take quite a while, and I would like to see the progress ffmpeg prints out.

If I start it with system(), I don't see the output.

If I use backticks, I get the output only after it is finished. Until then, I would have no idea what is going on.

There is also exec(), but that would terminate my perl script.

Is there yet another alternative?

Basically, I'm trying to do this:

#!/usr/bin/perl my $options = '....'; my @files = @ARGV || <>; foreach my $file (@files) { my $outfile = "$file.mov"; #### SOMETHING( "ffmpeg -i '$file' $options '$outfile'" ); }

where "something()" would either start the command in the current terminal and wait for it to finish, or maybe start a new terminal window, and also wait for it to finish.

  • Comment on start bash command from perl script: alternatives to system or backticks?
  • Download Code

Replies are listed 'Best First'.
Re: start bash command from perl script: alternatives to system or backticks?
by moritz (Cardinal) on Apr 28, 2010 at 13:54 UTC
    You can open a pipe with the -| open mode. See also perlopentut.
    Perl 6 - links to (nearly) everything that is Perl 6.
Re: start bash command from perl script: alternatives to system or backticks?
by ikegami (Patriarch) on Apr 28, 2010 at 14:06 UTC
    There's no reason you shouldn't see the output with system. Your script's STDOUT is inherited by the child.
    $ perl -e'system "ls .bash*"' .bash_history .bash_logout .bash_profile .bashrc
      You might also set $| so that your perl script does not buffer the output.
      #!perl $|++ ...
        $| will have absolutely no effect on children.
Re: start bash command from perl script: alternatives to system or backticks?
by jettero (Monsignor) on Apr 28, 2010 at 13:54 UTC

    A while back, I helped a co-worker (who is not a programmer) design and build this application that allows him to use his specialized video capture device reliably with Mythbuntu. It has plenty of example calls that do this kind of thing. The sources contain several examples of interacting with long running processes like ffmpeg.

    Most of the real work is done by IPC::System::Simple which handles the gorey details associated with this kind of programming; although, we used a healthy dose of IPC::Open3 as well.

    -Paul

Re: start bash command from perl script: alternatives to system or backticks?
by MidLifeXis (Monsignor) on Apr 28, 2010 at 14:02 UTC

    Perhaps something using open, such as

    open(my $ffmpeg, '-|', @command_and_args) or die "Blarg: $!"

    I have also seen a command line option on some long lived processing applications that tell it to put each update, or frequent updates, each on a new line on stdout for just this type of use case.

    --MidLifeXis

Re: start bash command from perl script: alternatives to system or backticks?
by JavaFan (Canon) on Apr 28, 2010 at 14:10 UTC
    If I start it with system(), I don't see the output.
    Really? If that is true, it's not really the fault of system - if you use system to call a program that writes to STDERR or STDOUT, than it will be connected to the programs STDERR or STDOUT. Could it be that your program is redirecting them? Or perhaps the called program is quiet if it isn't ran interactively? Or are you suffering from buffering?

    Without knowing why you aren't seeing the output, I cannot tell you what to do to see it.

Re: start bash command from perl script: alternatives to system or backticks?
by almut (Canon) on Apr 28, 2010 at 14:33 UTC
    ... or in a new window.

    If you want a separate window for the output, you can always start a new terminal emulator, and have it run a command via its -e option (-e applies to many terminals, in case of doubt, check the man page). For example

    system qw(xterm -e find / -type d);

    (xterm options (such as geometry, font size, etc.) would go before the -e)

    As soon as the command has finished, the terminal will automatically close.