readpipe#
Run a shell command and return its standard output.
readpipe hands EXPR to the shell, waits for the child to finish,
and returns whatever the child wrote to its standard output. It is the
named form of the qx (backticks) operator — `cmd` and
qx/cmd/ both compile down to readpipe. Reach for the named form
when you want the command in a variable, when you want to suppress
the double-quote interpolation qx performs, or when you want to
read a captured command out of @ARGV. If EXPR is omitted,
$_ is used.
Synopsis#
readpipe EXPR
readpipe
$out = readpipe $cmd;
@rows = readpipe $cmd;
What you get back#
Context decides the shape:
Scalar context — one string containing the entire captured output, newlines and all.
List context — a list of records, split on
$/(the input record separator, newline by default). The separator stays attached to each element unless youchompit off.
$? is set to the child’s wait status after the command finishes,
exactly as with system. A non-zero $? is the usual signal
that the command failed — the return value alone cannot tell you, since
a failing command may still have written output (or nothing) before
exiting.
my $out = readpipe "uname -a";
die "uname failed: \$? = $?" if $?;
Global state it touches#
$_— used as the command whenEXPRis omitted.$/— controls how list-context output is split into records. Set it toundefto slurp the whole output into a single element, or to""for paragraph mode.$?— set to the child’s wait status on return.$!— set if the shell itself could not be launched.%ENV— the shell inherits the current environment.
Examples#
Capture one line of output:
my $host = readpipe "hostname";
chomp $host;
print "running on $host\n";
Command held in a variable — the reason readpipe exists as a named
function. Backticks would still work here, but readpipe makes the
intent explicit and avoids the visual noise of nested quoting:
my $cmd = "ls -1 /etc";
my @entries = readpipe $cmd;
chomp @entries;
print scalar(@entries), " entries under /etc\n";
Slurp everything as one string by disabling record separation:
local $/; # slurp mode
my $log = readpipe "dmesg";
print length($log), " bytes of kernel log\n";
Paragraph mode — each element is one blank-line-separated block:
local $/ = "";
my @paragraphs = readpipe "cat README";
print scalar(@paragraphs), " paragraphs\n";
Check the exit status properly. The return value is output; success
lives in $?:
my @files = readpipe "find . -name '*.tmp' 2>/dev/null";
if ($? == 0) {
chomp @files;
unlink @files;
} else {
warn "find exited with status ", ($? >> 8), "\n";
}
Use $_ as the command. Rarely the clearest form, but legal:
$_ = "date";
my $when = readpipe; # same as readpipe $_
Edge cases#
No interpolation protection.
readpipeinterpolates its argument exactly like a double-quoted string — the same asqx.readpipe "rm $path"with$pathcoming from user input is a shell-injection hole. Quote the value, or better, switch to a list-formsystem/ pipedopenand skip the shell entirely.Standard error is not captured. Only the child’s standard output comes back. Redirect stderr in the command itself if you want it merged:
readpipe "cmd 2>&1".Shell is mandatory. Even a single-word
readpipe "true"goes through/bin/sh, which means shell quoting, globbing, and environment-variable expansion all apply. No list form exists.Large output buffers in memory. The whole child output is read before
readpipereturns. For a command that produces gigabytes, use a pipedopenand read incrementally instead.Empty output, zero exit. A successful command that writes nothing returns the empty string in scalar context and the empty list in list context. Distinguish “ran and said nothing” from “never ran” by checking
$?.Child died on signal.
$?encodes both exit code and signal — mask with$? & 127to get the signal number,$? >> 8for the exit code.Windows quoting rules.
readpipehands the string to the platform shell; on Windows that iscmd.exe, whose quoting and redirection rules differ from POSIX. pperl is Linux-only, so this is only relevant when porting scripts in.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
qx— the operator form;`cmd`andqx/cmd/are shorthand forreadpipeand carry identical semanticssystem— run a command without capturing output; use when you only care about exit statusexec— replace the current process with the command; no return, no captureopen— piped open (open my $fh, "-|", @cmd) streams the child’s output line-by-line without buffering it all$?— child wait status set by every process-launch builtin$/— input record separator that splits list-context output