tags:

views:

1449

answers:

6

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.

+4  A: 

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.

Chris Lutz
There's more than a page in perlop (section "Quote-Like Operators", subsection "qx/STRING/") as well as `perldoc -f readpipe`.
hobbs
http://perldoc.perl.org/perlop.html#Quote-Like-Operators I think.
seth
I found it. It seems I missed a forest for some trees. Or something.
Chris Lutz
+6  A: 

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.

hobbs
+2  A: 

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.

Chas. Owens
I wouldn't say that it's generally a mistake, just that you might be able to do that task in pure Perl. There are plenty of valid uses for system().
brian d foy
I am not saying calling `system` is a mistake, but most times people call it are mistakes. You need a good reason to call `system`.
Chas. Owens
A: 

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.

hillu
+4  A: 

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.

megamic
I just tried this module and it's great. Two thumbs up!
Kurt W. Leucht
+1  A: 

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 :)

depesz