8
votes

In Perl, to run another Perl script from my script, or to run any system commands like mv, cp, pkgadd, pkgrm, pkginfo, rpm etc, we can use the following:

  • system()
  • exec()
  • `` (Backticks)

Are all the three the same, or are they different? Do all the three give the same result in every case? Are they used in different scenarios, like to call a Perl program we have to use system() and for others we have to use ``(backticks).

Please advise, as I am currently using system() for all the calls.

6
This is not a duplicate, as that question does not mention exec().Daniel C. Sobral
No, but it is a duplicate of stackoverflow.com/questions/799968/… :)Robert P

6 Answers

13
votes

They're all different, and the docs explain how they're different. Backticks capture and return output; system returns an exit status, and exec never returns at all if it's successful.

6
votes

IPC::System::Simple is probably what you want.

It provides safe, portable alternatives to backticks, system() and other IPC commands.

It also allows you to avoid the shell for most of said commands, which can be helpful in some circumstances.

3
votes

The best option is to use some module, either in the standard library or from CPAN, that does the job for you. It's going to be more portable, and possibly even faster for quick tasks (no forking to the system).

However, if that's not good enough for you, you can use one of those three, and no, they are not the same. Read the perldoc pages on system(), exec(), and backticks to see the difference.

1
votes

Calling system is generally a mistake. For instance, instead of saying

system "mv $foo /tmp" == 0
    or die "could not move $foo to /tmp";

system "cp $foo /tmp" == 0
    or die "could not copy $foo to /tmp";

you should say

use File::Copy;

move $foo, "/tmp"
    or die "could not move $foo to /tmp: $!";

copy $foo, "/tmp"
    or die "could not copy $foo to /tmp: $!";

Look on CPAN for modules that handle other commands for you. If you find yourself writing a lot of calls to system, it may be time to drop back into a shell script instead.

1
votes

Well, the more people the more answers.

My answer is to generally avoid external commands execution. If you can - use modules. There is no point executing "cp", "mv" and a lot of another command - there exist modules that do it. And the benefit of using modules is that they usually work cross-platform. While your system("mv") might not.

When put in situation that I have no other way, but to call external command, I prefer to use IPC::Run. The idea is that all simplistic methods (backticks, qx, system, open with pipe) are inherently insecure, and require attention to parameters.

With IPC::Run, I run commands like I would do with system( @array ), which is much more secure, and I can bind to stdin, stdout and stderr separately, using variables, or callbacks, which is very cool when you'll be in situation that you have to pass data to external program from long-running code.

Also, it has built-in handling of timeouts, which come handy more than once :)

-1
votes

If you don't want the shell getting involved (usually you don't) and if waiting for the system command is acceptable, I recommend using IPC::Run3. It is simple, flexible, and does the common task of executing a program, feeding it input and capturing its output and error streams right.