Gathering Output from a Program
Problem
You want to run a program and collect its output into a variable.
Solution
Either use backticks:
$output = `program args`; # collect output into one multiline string @output = `program args`; # collect output into array, one line per element
Or use Section 16.4:
open(README, "program args |") or die "Can't run program: $!\n"; while(<README>) { $output .= $_; } close(README);
Discussion
The backticks are a convenient way to run other programs and gather their output. The backticks do not return until the called program exits. Perl goes to some trouble behind the scenes to collect the output, so it is inefficient to use the backticks and ignore their return value:
`fsck -y /dev/rsd1a`; # BAD AND SCARY
Both the open
function and the backtick operator
call the shell to run their commands. This makes them unsafe when
used in a program with special privileges.
A high-level workaround is given in Section 19.6.
Here’s a low-level workaround, using pipe
,
fork
, and exec
:
use POSIX qw(:sys_wait_h); pipe(README, WRITEME); if ($pid = fork) { # parent $SIG{CHLD} = sub { 1 while ( waitpid(-1, WNOHANG)) > 0 }; close(WRITEME); } else { die "cannot fork: $!" unless defined $pid; # child open(STDOUT, ">&=WRITEME") or die "Couldn't redirect STDOUT: $!"; close(README); exec($program, $arg1, $arg2) or die "Couldn't run $program : $!\n"; } while (<README>) { $string .= $_; # or push(@strings, $_); } close(README);
See Also
The section on “Cooperating with Strangers” ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.