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

Dear Monks, I wanted to ask your opinion regarding which is the optimal way to call external programs through a perl script...
To make it clear, these programs are totally independent from my main script and cannot be merged into it, they form complete software.
Which means that I need to call them and run them. Is  system the correct way for this or another function is more recommended?

Replies are listed 'Best First'.
Re: Calling external commands through my script
by kennethk (Abbot) on Feb 25, 2014 at 00:36 UTC
    How you should call them depends upon your needs. Do you need to process their inputs or outputs through Perl? Do you want the external call to be blocking? Do you want to implement time-outs? What OS are you on?

    Options include:

    and more. See perlipc for some important detail.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      It's actually that I want to call the program, which will run and then create a file that I will process. Everything is done on Linux OS. So you think <system> is OK to go, right?
        system is a good solution if the program should be blocking, you have no need to interact with STDIN/STDOUT/STDERR, and you don't need to worry about a timeout. Be aware that any STDOUT or STDERR the program generates will just get tacked onto your perl IO channels.

        I'd recommend using a list-based call to avoid escaping complications (e.g. system($executable, @args);) but again, that's generic advice.


        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Calling external commands through my script
by kcott (Archbishop) on Feb 25, 2014 at 01:11 UTC

    The answer to this will depend on how your Perl script needs to interact with the external program. Here's a non-exhaustive list of possibilities:

    • You want to wait for the program to finish and check its exit status: system may be best.
    • You want the output from the program: qx{...} (or `...`) may be the best choice — see perlop: Quote-Like Operators for details.
    • You want control over how (one of) input or output is written to or read from the program: perhaps choose open with a mode of '|-' or '-|' — see perlipc: Using open() for IPC for more details.
    • See perlipc for more complex scenarios, such as bidirectional and client/server communication.
    • There are also many modules that may do exactly what you want, e.g. the built-in IPC::* modules.

    If you provide a clearer picture of your requirements, we can provide a better answer.

    -- Ken

Re: Calling external commands through my script
by Athanasius (Archbishop) on Feb 25, 2014 at 04:33 UTC

    Another useful option is the module Capture::Tiny, which combines with system to return the external programme’s exit status while also capturing its output to STDOUT and to STDERR. For example:

    use Capture::Tiny 'capture'; ... my ($stdout, $stderr, $exit) = capture { system($cmd, @args); };

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Calling external commands through my script
by ww (Archbishop) on Feb 25, 2014 at 00:40 UTC
    You'll also find informative reading in the (on-site) links you'll find with Super Search and likely with a simple search using Google, DuckDuckGo or some other search engine.

    And those are recommended as step one before the next time you ask such an inspecific question.

    Come, let us reason together: Spirit of the Monastery