What's the difference between Perl's backticks, system, and exec?
Asked Answered
H

6

268

Can someone please help me? In Perl, what is the difference between:

exec "command";

and

system("command");

and

print `command`;

Are there other ways to run shell commands too?

Hemelytron answered 28/4, 2009 at 21:47 Comment(1)
Almost an exact duplicate of #797627, except that this one has exec and the other one has pipes.Icehouse
A
294

exec

executes a command and never returns. It's like a return statement in a function.

If the command is not found exec returns false. It never returns true, because if the command is found it never returns at all. There is also no point in returning STDOUT, STDERR or exit status of the command. You can find documentation about it in perlfunc, because it is a function.

system

executes a command and your Perl script is continued after the command has finished.

The return value is the exit status of the command. You can find documentation about it in perlfunc.

backticks

like system executes a command and your perl script is continued after the command has finished.

In contrary to system the return value is STDOUT of the command. qx// is equivalent to backticks. You can find documentation about it in perlop, because unlike system and execit is an operator.


Other ways

What is missing from the above is a way to execute a command asynchronously. That means your perl script and your command run simultaneously. This can be accomplished with open. It allows you to read STDOUT/STDERR and write to STDIN of your command. It is platform dependent though.

There are also several modules which can ease this tasks. There is IPC::Open2 and IPC::Open3 and IPC::Run, as well as Win32::Process::Create if you are on windows.

Alignment answered 28/4, 2009 at 22:7 Comment(5)
I think you mean s/perlcunc/perlfunc/ ... also the perlipc documentation goes into great depth about opening pipes.Prosit
perlcunc, maybe this will be my new nick name;-)Alignment
For the record, backticks and qx[] also populate $? (the OS return value).Demulcent
In list context, backticks returns a list of lines that were the output of the command. In scalar context, it returns them as a single string joined with newlines.Stipend
Re "because unlike system and exec it is an operator" All three are operators. system and exec are named list operators, which is why they're documented in perlfunc along with the other named list operators, named unary operators and named nulary operators.Kirst
D
175

In general I use system, open, IPC::Open2, or IPC::Open3 depending on what I want to do. The qx// operator, while simple, is too constraining in its functionality to be very useful outside of quick hacks. I find open to much handier.

system: run a command and wait for it to return

Use system when you want to run a command, don't care about its output, and don't want the Perl script to do anything until the command finishes.

#doesn't spawn a shell, arguments are passed as they are
system("command", "arg1", "arg2", "arg3");

or

#spawns a shell, arguments are interpreted by the shell, use only if you
#want the shell to do globbing (e.g. *.txt) for you or you want to redirect
#output
system("command arg1 arg2 arg3");

qx// or ``: run a command and capture its STDOUT

Use qx// when you want to run a command, capture what it writes to STDOUT, and don't want the Perl script to do anything until the command finishes.

#arguments are always processed by the shell

#in list context it returns the output as a list of lines
my @lines = qx/command arg1 arg2 arg3/;

#in scalar context it returns the output as one string
my $output = qx/command arg1 arg2 arg3/;

exec: replace the current process with another process.

Use exec along with fork when you want to run a command, don't care about its output, and don't want to wait for it to return. system is really just

sub my_system {
    die "could not fork\n" unless defined(my $pid = fork);
    return waitpid $pid, 0 if $pid; #parent waits for child
    exec @_; #replace child with new process
}

You may also want to read the waitpid and perlipc manuals.

open: run a process and create a pipe to its STDIN or STDERR

Use open when you want to write data to a process's STDIN or read data from a process's STDOUT (but not both at the same time).

#read from a gzip file as if it were a normal file
open my $read_fh, "-|", "gzip", "-d", $filename
    or die "could not open $filename: $!";

#write to a gzip compressed file as if were a normal file
open my $write_fh, "|-", "gzip", $filename
    or die "could not open $filename: $!";

IPC::Open2: run a process and create a pipe to both STDIN and STDOUT

Use IPC::Open2 when you need to read from and write to a process's STDIN and STDOUT.

use IPC::Open2;

open2 my $out, my $in, "/usr/bin/bc"
    or die "could not run bc";

print $in "5+6\n";

my $answer = <$out>;

IPC::Open3: run a process and create a pipe to STDIN, STDOUT, and STDERR

use IPC::Open3 when you need to capture all three standard file handles of the process. I would write an example, but it works mostly the same way IPC::Open2 does, but with a slightly different order to the arguments and a third file handle.

Dribble answered 28/4, 2009 at 22:32 Comment(3)
Very informative and upto date answer. Thanks @chas-owensRattlebrain
IPC::Open3 is too low-level for most uses. IPC::Run3 and IPC::Run are usually far more appropriate.Kirst
Does this also spawn a shell: my @cmd = ("cmd", "param1"); system (@cmd);Bickerstaff
M
18

Let me quote the manuals first:

perldoc exec():

The exec function executes a system command and never returns-- use system instead of exec if you want it to return

perldoc system():

Does exactly the same thing as exec LIST , except that a fork is done first, and the parent process waits for the child process to complete.

In contrast to exec and system, backticks don't give you the return value but the collected STDOUT.

perldoc `String`:

A string which is (possibly) interpolated and then executed as a system command with /bin/sh or its equivalent. Shell wildcards, pipes, and redirections will be honored. The collected standard output of the command is returned; standard error is unaffected.


Alternatives:

In more complex scenarios, where you want to fetch STDOUT, STDERR or the return code, you can use well known standard modules like IPC::Open2 and IPC::Open3.

Example:

use IPC::Open2;
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'some', 'cmd', 'and', 'args');
waitpid( $pid, 0 );
my $child_exit_status = $? >> 8;

Finally, IPC::Run from the CPAN is also worth looking at…

Metchnikoff answered 28/4, 2009 at 22:1 Comment(4)
This is a rude response. You should try to be helpful without the anger.Participate
I think he was just making a reference to the ol' RTFM :PGorlicki
wasn't meant rude actually ;) removed the f-word though, to avoid any misunderstandings…Metchnikoff
I certainly didn't interpret it as being rude. Brusque, maybe, but this is not a highly-intelligent question requiring a thoughtful answer.Prosit
H
14

What's the difference between Perl's backticks (`), system, and exec?

exec -> exec "command"; ,
system -> system("command"); and 
backticks -> print `command`;

exec

exec executes a command and never resumes the Perl script. It's to a script like a return statement is to a function.

If the command is not found, exec returns false. It never returns true, because if the command is found, it never returns at all. There is also no point in returning STDOUT, STDERR or exit status of the command. You can find documentation about it in perlfunc, because it is a function.

E.g.:

#!/usr/bin/perl
print "Need to start exec command";
my $data2 = exec('ls');
print "Now END exec command";
print "Hello $data2\n\n";

In above code, there are three print statements, but due to exec leaving the script, only the first print statement is executed. Also, the exec command output is not being assigned to any variable.

Here, only you're only getting the output of the first print statement and of executing the ls command on standard out.

system

system executes a command and your Perl script is resumed after the command has finished. The return value is the exit status of the command. You can find documentation about it in perlfunc.

E.g.:

#!/usr/bin/perl
print "Need to start system command";
my $data2 = system('ls');
print "Now END system command";
print "Hello $data2\n\n";

In above code, there are three print statements. As the script is resumed after the system command, all three print statements are executed.

Also, the result of running system is assigned to data2, but the assigned value is 0 (the exit code from ls).

Here, you're getting the output of the first print statement, then that of the ls command, followed by the outputs of the final two print statements on standard out.

backticks (`)

Like system, enclosing a command in backticks executes that command and your Perl script is resumed after the command has finished. In contrast to system, the return value is STDOUT of the command. qx// is equivalent to backticks. You can find documentation about it in perlop, because unlike system and exec, it is an operator.

E.g.:

#!/usr/bin/perl
print "Need to start backticks command";
my $data2 = `ls`;
print "Now END system command";
print "Hello $data2\n\n";

In above code, there are three print statements and all three are being executed. The output of ls is not going to standard out directly, but assigned to the variable data2 and then printed by the final print statement.

Hurdle answered 4/6, 2016 at 11:12 Comment(1)
In summary, exec executes and never comeback. system executes and comeback with exit code backticks executes and comeback with result of the execution.Schenk
P
3

The difference between 'exec' and 'system' is that exec replaces your current program with 'command' and NEVER returns to your program. system, on the other hand, forks and runs 'command' and returns you the exit status of 'command' when it is done running. The back tick runs 'command' and then returns a string representing its standard out (whatever it would have printed to the screen)

You can also use popen to run shell commands and I think that there is a shell module - 'use shell' that gives you transparent access to typical shell commands.

Hope that clarifies it for you.

Participate answered 28/4, 2009 at 22:1 Comment(6)
Perhaps you mean use Shell; (search.cpan.org/dist/Shell/Shell.pm)? It's not widely installed, nor is it applicable to the question, I think...Prosit
The last part of his question was "are there other ways to run shell commands too" - Shell is another way to run shell commands.Participate
The docs specifically state "This package is included as a show case, illustrating a few Perl features. It shouldn't be used for production programs. Although it does provide a simple interface for obtaining the standard output of arbitrary commands, there may be better ways of achieving what you need."Dribble
Again, it answered his question of 'are there other ways'Participate
Bad, unsupported ways should not be given without warnings that they are bad and unsupported.Dribble
@ephemient: "not widely installed"? Try running "corelist Shell". You'll get "Shell was first released with perl 5". That is perl 5.000. It's been part of the perl core for ages! :)Nadinenadir
S
0

In summary,

  • exec executes and never comeback.
  • system executes and comeback with exit code.
  • backticks executes and comeback with result of the execution.
Schenk answered 25/10, 2023 at 5:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.