When we run a program with
shell we get a
Proc object. We can redirect in- and output on it.
Let us revisit this command from Part 3: The Execution:
shell 'ls -lR | gzip -9 > ls-lR.gz';
Here it is implement with
my $fh = open :w, :bin, "ls-lR.gz"; my $proc1 = run <ls -lR>, :out; my $proc2 = run <gzip -9>, :in($proc1.out), :out($fh); $fh.close;
And as an unreadable one-liner without all the variables (and shown here on two lines to make it somewhat easier to read):File: run-io2
run <gzip -9>, :in((run <ls -lR>, :out).out), :out(open :w, :bin, "ls-lR.gz");
This works with in- and ouput for
well, but it is easier to let the shell do it for us (as shown in the example).
See docs.raku.org/type/Proc for more
We can handle STDERR as well, with
We can catch the output, by calling
out on the
> my $proc = run <ls -lR>, :out; > my $output = $proc.out.slurp(:close);
:close is required, as the filehandle will be left open otherwise.
> my $proc = run <ls -lR>, :out; > say $proc.out.WHAT; (Pipe)
docs.perl6.org/type/IO::Pipe for more information about
WHAT is a Metamethod that gives the type of
the object. See
for more information.
Quoting is normally done with 'single quotes' (which does not interpolate variables) and "double quotes" (which does interpolate them).
We can also use the
qq/.../ construct, where
q is the same as single quoting, and
> my $a = 122; > say q/This is $a/; # -> This is $a > say qq/This is $a/; # -> This is 122
This quoting construct will execute (as a program) whatever is inside the quotes.
If we use
qx, the return value is the output from the program. And
we have no way of getting at the
Proc object (and status codes).
> say "** " ~ qx/date/ ~ " **"; ** Sa. 11. April 13:43:11 +0200 2020 **
> say "** " ~ qx/date/.chomp ~ " **"; ** Sa. 11. April 13:43:11 +0200 2020 **
The shell will complain (to STDOUT) if it doesn't find the program:
> say "** " ~ qx/foo.bar/.chomp ~ " **"; /bin/sh: 1: foo.bar: not found ** **
for more information about
qx version of the «hostname» program looks like this:
shell version is shorter:
The program handles the output, so we don't even have to do a
We can do it the hard way, by capturing the output and printing it ourself:File: hostname-proc
my $proc = shell "hostname", :out; my $host = $proc.out.slurp(:close); print $host;
We can swap
run, but it doesn't make a
difference in this case.
qx does not not do variable interpolation. Use
if you require interpolation:
my $cmd = "hostname"; print qqx/$cmd/;
Be very careful if you do this, as you may end up running harmful commands.
There will be a 7th part «The Promise» in a couple of weeks, and that is a promise.