Processes

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 you chomp it 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 when EXPR is omitted.

  • $/ — controls how list-context output is split into records. Set it to undef to 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. readpipe interpolates its argument exactly like a double-quoted string — the same as qx. readpipe "rm $path" with $path coming from user input is a shell-injection hole. Quote the value, or better, switch to a list-form system / piped open and 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 readpipe returns. For a command that produces gigabytes, use a piped open and 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 $? & 127 to get the signal number, $? >> 8 for the exit code.

  • Windows quoting rules. readpipe hands the string to the platform shell; on Windows that is cmd.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` and qx/cmd/ are shorthand for readpipe and carry identical semantics

  • system — run a command without capturing output; use when you only care about exit status

  • exec — replace the current process with the command; no return, no capture

  • open — 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