![]() | ![]() |
16.2. Running Another Program
16.2.1. Problem
From one program you want to run
another, pause until it is done, and then continue with the original
program. The other program should have the same
STDIN and STDOUT as you have.
16.2.2. Solution
Call system with a
string to have the shell interpret the string as a command line:
$status = system("vi $myfile");
If you don't want the shell involved, pass system
a list:
$status = system("vi", $myfile);
16.2.3. Discussion
The system function is the simplest and most
generic way to run another program in Perl. It doesn't gather the
program's STDOUT like backticks or
open. Instead, its return value is (essentially)
that program's exit status. While the new program is running, your
main program is suspended, so the new program can read from your
STDIN and write to your STDOUT
so users can interact with it.
system("cmd1 args | cmd2 | cmd3 >outfile");
system("cmd args < infile >outfile 2>errfile");
To avoid the shell, call system with a list of
arguments:
$status = system($program, $arg1, $arg);
die "$program exited funny: $?" unless $status = = 0;
The returned status value is not just the exit value: it includes the
signal number (if any) that the process died from. This is the same
value that wait sets $? to. See
Recipe 16.19 to learn how to decode this
value.
The system function ignores
SIGINT and SIGQUIT while child
processes are running. That way those signals will kill only the
child process. If you want your main program to die as well, check
the return value of system or the value of the
$? variable.
if (($signo = system(@arglist)) &= 127) {
die "program killed by signal $signo\n";
}
A few programs examine their own program name. Shells look to see
whether they were called with a leading minus to indicate
interactivity. The expn program at the end of
Chapter 18 behaves differently if called as
vrfy, which can happen if you've installed the
file under two different links as suggested. This is why you
shouldn't trust that $0 is really the pathname to
the invoked program—you could have been lied to in a number of
ways.
If you want to fib to the program you're executing about its own
name, specify the real path as the "indirect object" in front of the
list passed to system. (This also works with
exec.) The indirect object has no comma following
it, just like using printf with a filehandle or
making object methods without the pointer arrow.
$shell = '/bin/tcsh';
system $shell '-csh'; # pretend it's a login shell
Or, more directly:
system {'/bin/tcsh'} '-csh'; # pretend it's a login shell
In the next example, the program's real pathname is supplied in the
indirect object slot as
{'/home/tchrist/scripts/expn'}. The fictitious
name 'vrfy' is given as the first real function
argument, which the program will see stored in $0.
# call expn as vrfy
system {'/home/tchrist/scripts/expn'} 'vrfy', @ADDRESSES;
Using an indirect object with system is also more
secure. This usage forces interpretation of the arguments as a
multivalued list, even if the list had just one argument. That way
you're safe from the shell expanding wildcards or splitting up words
with whitespace in them.
@args = ( "echo surprise" );
system @args;# subject to shell escapes if @args = = 1
system { $args[0] } @args; # safe even with one-arg list
The first version, the one without the indirect object, ran the
echo program, passing it
"surprise" as an argument. The second version
didn't—it tried to run a program literally called
"echo surprise", didn't find
it, and set $? to a non-zero value indicating
failure.
16.2.4. See Also
The section on "Talking to Yourself" in Chapter 16 of
Programming Perl or
perlsec(1); the waitpid,
fork, exec,
system, and open functions in
Chapter 29 of Programming Perl, or
perlfunc(1); Recipe 16.1; Recipe 16.4; Recipe 16.19; Recipe 19.5;
Advanced Programming in the UNIX Environment,
by Richard W. Stevens (Addison-Wesley)
![]() | ![]() | ![]() |
16.1. Gathering Output from a Program | ![]() | 16.3. Replacing the Current Program with a Different One |

Copyright © 2003 O'Reilly & Associates. All rights reserved.