Running external CLI tool and capturing output

The documentation has a nice example showing how to run an external
program and how to get its output or even its standard error.
https://docs.perl6.org/type/Proc

However it looks a lot more complex than the plain backtick Perl 5 has
and more complex than the capture function of Capture::Tiny.
IMHO it is way too much code.

I wrote a simple function wrapping it:

sub capture(*@args) {
    my $p = run @args, :out, :err;
    my $output = $p.out.slurp: :close;
    my $error  = $p.err.slurp: :close;
    my $exit   = $p.exitcode;

    return {
        out  => $output,
        err  => $error,
        exit => $exit;
    };
}

It can be used as:

my $res = capture($*EXECUTABLE, 'bin/create_db.pl6');
say $res<out>;

or even

say capture($*EXECUTABLE, 'bin/create_db.pl6')<out>;

I wonder if I have just invented something that already exist in
Rakudo or if it is not there, then wouldn't it be a good idea to add
such a simple way to run external commands?

regards
   Gabor
ps. Backtick actually expected a single string and not a list of
parameters and supporting that mode, even if it is less secure, might
be also a good idea.
0
szabgab
8/10/2017 2:57:24 PM
perl.perl6.users 832 articles. 0 followers. Follow

4 Replies
13 Views

Similar Articles

[PageSpeed] 49

--94eb2c094c5cc8acca0556677627
Content-Type: text/plain; charset="UTF-8"

"ps. security bad, correctness bad, do the simplest thing even when it's
wrong."

On Thu, Aug 10, 2017 at 10:57 AM, Gabor Szabo <szabgab@gmail.com> wrote:

> The documentation has a nice example showing how to run an external
> program and how to get its output or even its standard error.
> https://docs.perl6.org/type/Proc
>
> However it looks a lot more complex than the plain backtick Perl 5 has
> and more complex than the capture function of Capture::Tiny.
> IMHO it is way too much code.
>
> I wrote a simple function wrapping it:
>
> sub capture(*@args) {
>     my $p = run @args, :out, :err;
>     my $output = $p.out.slurp: :close;
>     my $error  = $p.err.slurp: :close;
>     my $exit   = $p.exitcode;
>
>     return {
>         out  => $output,
>         err  => $error,
>         exit => $exit;
>     };
> }
>
> It can be used as:
>
> my $res = capture($*EXECUTABLE, 'bin/create_db.pl6');
> say $res<out>;
>
> or even
>
> say capture($*EXECUTABLE, 'bin/create_db.pl6')<out>;
>
> I wonder if I have just invented something that already exist in
> Rakudo or if it is not there, then wouldn't it be a good idea to add
> such a simple way to run external commands?
>
> regards
>    Gabor
> ps. Backtick actually expected a single string and not a list of
> parameters and supporting that mode, even if it is less secure, might
> be also a good idea.
>



-- 
brandon s allbery kf8nh                               sine nomine associates
allbery.b@gmail.com                                  ballbery@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net

--94eb2c094c5cc8acca0556677627
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">&quot;ps. security bad, correctness bad, do the simplest t=
hing even when it&#39;s wrong.&quot;</div><div class=3D"gmail_extra"><br><d=
iv class=3D"gmail_quote">On Thu, Aug 10, 2017 at 10:57 AM, Gabor Szabo <spa=
n dir=3D"ltr">&lt;<a href=3D"mailto:szabgab@gmail.com" target=3D"_blank">sz=
abgab@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The=
 documentation has a nice example showing how to run an external<br>
program and how to get its output or even its standard error.<br>
<a href=3D"https://docs.perl6.org/type/Proc" rel=3D"noreferrer" target=3D"_=
blank">https://docs.perl6.org/type/<wbr>Proc</a><br>
<br>
However it looks a lot more complex than the plain backtick Perl 5 has<br>
and more complex than the capture function of Capture::Tiny.<br>
IMHO it is way too much code.<br>
<br>
I wrote a simple function wrapping it:<br>
<br>
sub capture(*@args) {<br>
=C2=A0 =C2=A0 my $p =3D run @args, :out, :err;<br>
=C2=A0 =C2=A0 my $output =3D $p.out.slurp: :close;<br>
=C2=A0 =C2=A0 my $error=C2=A0 =3D $p.err.slurp: :close;<br>
=C2=A0 =C2=A0 my $exit=C2=A0 =C2=A0=3D $p.exitcode;<br>
<br>
=C2=A0 =C2=A0 return {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 out=C2=A0 =3D&gt; $output,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 err=C2=A0 =3D&gt; $error,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 exit =3D&gt; $exit;<br>
=C2=A0 =C2=A0 };<br>
}<br>
<br>
It can be used as:<br>
<br>
my $res =3D capture($*EXECUTABLE, &#39;bin/create_db.pl6&#39;);<br>
say $res&lt;out&gt;;<br>
<br>
or even<br>
<br>
say capture($*EXECUTABLE, &#39;bin/create_db.pl6&#39;)&lt;out&gt;;<br>
<br>
I wonder if I have just invented something that already exist in<br>
Rakudo or if it is not there, then wouldn&#39;t it be a good idea to add<br=
>
such a simple way to run external commands?<br>
<br>
regards<br>
<span class=3D"HOEnZb"><font color=3D"#888888">=C2=A0 =C2=A0Gabor<br>
</font></span>ps. Backtick actually expected a single string and not a list=
 of<br>
parameters and supporting that mode, even if it is less secure, might<br>
be also a good idea.<br>
</blockquote></div><br><br clear=3D"all"><div><br></div>-- <br><div class=
=3D"gmail_signature" data-smartmail=3D"gmail_signature"><div dir=3D"ltr"><d=
iv>brandon s allbery kf8nh =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sine nomine associ=
ates</div><div><a href=3D"mailto:allbery.b@gmail.com" target=3D"_blank">all=
bery.b@gmail.com</a> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<a href=
=3D"mailto:ballbery@sinenomine.net" target=3D"_blank">ballbery@sinenomine.n=
et</a></div><div>unix, openafs, kerberos, infrastructure, xmonad =C2=A0 =C2=
=A0 =C2=A0 =C2=A0<a href=3D"http://sinenomine.net" target=3D"_blank">http:/=
/sinenomine.net</a></div></div></div>
</div>

--94eb2c094c5cc8acca0556677627--
0
allbery
8/10/2017 3:00:57 PM
--001a113d4bec5bb0360556679405
Content-Type: text/plain; charset="UTF-8"

How about qx and qxx? I guess those don't separate/capture stderr, and
don't separate out the params.

--Brock


On Thu, Aug 10, 2017 at 10:57 AM, Gabor Szabo <szabgab@gmail.com> wrote:

> The documentation has a nice example showing how to run an external
> program and how to get its output or even its standard error.
> https://docs.perl6.org/type/Proc
>
> However it looks a lot more complex than the plain backtick Perl 5 has
> and more complex than the capture function of Capture::Tiny.
> IMHO it is way too much code.
>
> I wrote a simple function wrapping it:
>
> sub capture(*@args) {
>     my $p = run @args, :out, :err;
>     my $output = $p.out.slurp: :close;
>     my $error  = $p.err.slurp: :close;
>     my $exit   = $p.exitcode;
>
>     return {
>         out  => $output,
>         err  => $error,
>         exit => $exit;
>     };
> }
>
> It can be used as:
>
> my $res = capture($*EXECUTABLE, 'bin/create_db.pl6');
> say $res<out>;
>
> or even
>
> say capture($*EXECUTABLE, 'bin/create_db.pl6')<out>;
>
> I wonder if I have just invented something that already exist in
> Rakudo or if it is not there, then wouldn't it be a good idea to add
> such a simple way to run external commands?
>
> regards
>    Gabor
> ps. Backtick actually expected a single string and not a list of
> parameters and supporting that mode, even if it is less secure, might
> be also a good idea.
>

--001a113d4bec5bb0360556679405
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">How about qx and qxx? I guess those don&#39;t separate/cap=
ture stderr, and don&#39;t separate out the params.<div><br></div><div>--Br=
ock</div><div><br></div></div><div class=3D"gmail_extra"><br><div class=3D"=
gmail_quote">On Thu, Aug 10, 2017 at 10:57 AM, Gabor Szabo <span dir=3D"ltr=
">&lt;<a href=3D"mailto:szabgab@gmail.com" target=3D"_blank">szabgab@gmail.=
com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The documentati=
on has a nice example showing how to run an external<br>
program and how to get its output or even its standard error.<br>
<a href=3D"https://docs.perl6.org/type/Proc" rel=3D"noreferrer" target=3D"_=
blank">https://docs.perl6.org/type/<wbr>Proc</a><br>
<br>
However it looks a lot more complex than the plain backtick Perl 5 has<br>
and more complex than the capture function of Capture::Tiny.<br>
IMHO it is way too much code.<br>
<br>
I wrote a simple function wrapping it:<br>
<br>
sub capture(*@args) {<br>
=C2=A0 =C2=A0 my $p =3D run @args, :out, :err;<br>
=C2=A0 =C2=A0 my $output =3D $p.out.slurp: :close;<br>
=C2=A0 =C2=A0 my $error=C2=A0 =3D $p.err.slurp: :close;<br>
=C2=A0 =C2=A0 my $exit=C2=A0 =C2=A0=3D $p.exitcode;<br>
<br>
=C2=A0 =C2=A0 return {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 out=C2=A0 =3D&gt; $output,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 err=C2=A0 =3D&gt; $error,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 exit =3D&gt; $exit;<br>
=C2=A0 =C2=A0 };<br>
}<br>
<br>
It can be used as:<br>
<br>
my $res =3D capture($*EXECUTABLE, &#39;bin/create_db.pl6&#39;);<br>
say $res&lt;out&gt;;<br>
<br>
or even<br>
<br>
say capture($*EXECUTABLE, &#39;bin/create_db.pl6&#39;)&lt;out&gt;;<br>
<br>
I wonder if I have just invented something that already exist in<br>
Rakudo or if it is not there, then wouldn&#39;t it be a good idea to add<br=
>
such a simple way to run external commands?<br>
<br>
regards<br>
<span class=3D"HOEnZb"><font color=3D"#888888">=C2=A0 =C2=A0Gabor<br>
</font></span>ps. Backtick actually expected a single string and not a list=
 of<br>
parameters and supporting that mode, even if it is less secure, might<br>
be also a good idea.<br>
</blockquote></div><br></div>

--001a113d4bec5bb0360556679405--
0
awwaiid
8/10/2017 3:09:13 PM
Oh right. Thanks. I forgot about them. Maybe
https://docs.perl6.org/routine/run should mention them as well.

In any case a simpler way to capture everything might be useful.

Gabor

On Thu, Aug 10, 2017 at 6:09 PM, Brock Wilcox
<awwaiid@thelackthereof.org> wrote:
> How about qx and qxx? I guess those don't separate/capture stderr, and don't
> separate out the params.
>
> --Brock
>
>
> On Thu, Aug 10, 2017 at 10:57 AM, Gabor Szabo <szabgab@gmail.com> wrote:
>>
>> The documentation has a nice example showing how to run an external
>> program and how to get its output or even its standard error.
>> https://docs.perl6.org/type/Proc
>>
>> However it looks a lot more complex than the plain backtick Perl 5 has
>> and more complex than the capture function of Capture::Tiny.
>> IMHO it is way too much code.
>>
>> I wrote a simple function wrapping it:
>>
>> sub capture(*@args) {
>>     my $p = run @args, :out, :err;
>>     my $output = $p.out.slurp: :close;
>>     my $error  = $p.err.slurp: :close;
>>     my $exit   = $p.exitcode;
>>
>>     return {
>>         out  => $output,
>>         err  => $error,
>>         exit => $exit;
>>     };
>> }
>>
>> It can be used as:
>>
>> my $res = capture($*EXECUTABLE, 'bin/create_db.pl6');
>> say $res<out>;
>>
>> or even
>>
>> say capture($*EXECUTABLE, 'bin/create_db.pl6')<out>;
>>
>> I wonder if I have just invented something that already exist in
>> Rakudo or if it is not there, then wouldn't it be a good idea to add
>> such a simple way to run external commands?
>>
>> regards
>>    Gabor
>> ps. Backtick actually expected a single string and not a list of
>> parameters and supporting that mode, even if it is less secure, might
>> be also a good idea.
0
szabgab
8/10/2017 3:28:17 PM
--f403045e9f2e50e36e0556681bc3
Content-Type: text/plain; charset="UTF-8"

On Thu, Aug 10, 2017 at 11:28 Gabor Szabo <szabgab@gmail.com> wrote:

> Oh right. Thanks. I forgot about them. Maybe
> https://docs.perl6.org/routine/run should mention them as well.
>
> In any case a simpler way to capture everything might be useful.


Maybe not simpler but take a look at my published Perl 6 module
"Proc::More" and its  "run-command".

-Tom

--f403045e9f2e50e36e0556681bc3
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div>On Thu, Aug 10, 2017 at 11:28 Gabor Szabo &lt;<a href=3D"mailto:szabga=
b@gmail.com">szabgab@gmail.com</a>&gt; wrote:<br><div class=3D"gmail_quote"=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex">Oh right. Thanks. I forgot about them. Mayb=
e<br>
<a href=3D"https://docs.perl6.org/routine/run" rel=3D"noreferrer" target=3D=
"_blank">https://docs.perl6.org/routine/run</a> should mention them as well=
..<br>
<br>
In any case a simpler way to capture everything might be useful.</blockquot=
e><div dir=3D"auto"><br></div><div dir=3D"auto">Maybe not simpler but take =
a look at my published Perl 6 module &quot;Proc::More&quot; and its =C2=A0&=
quot;run-command&quot;.</div><div dir=3D"auto"><br></div><div dir=3D"auto">=
-Tom</div></div></div>

--f403045e9f2e50e36e0556681bc3--
0
tom
8/10/2017 3:46:47 PM
Reply: