Skip Menu |
Report information
Id: 125757
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: alex.jakimenko [at] gmail.com
comdog <brian.d.foy [at] gmail.com>
rob [at] hoelz.ro
Cc:
AdminCc:

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Subject: shell().exitcode is always 0 when :out is used
See the attached script.
Subject: test.pl
Download test.pl
text/x-perl 119b
use v6; use Test; plan 1; my $p = shell('false', :out); isnt $p.exitcode, 0, 'exit code of false should not be 0';
On 2015-08-05 10:32:54, rob@hoelz.ro wrote: Show quoted text
> See the attached script. >
Same goes for run().
Download (untitled) / with headers
text/plain 193b
On Wed Aug 05 10:32:54 2015, rob@hoelz.ro wrote: Show quoted text
> See the attached script. >
It works if you close the file handle: perl6 -e 'my $p = shell("false", :out); $p.out.close; say $p.exitcode' 1
Shall we attempt to make the exitcode (Int) until we got one?
Download (untitled) / with headers
text/plain 128b
On 2015-08-05 23:20:24, FROGGS.de wrote: Show quoted text
> Shall we attempt to make the exitcode (Int) until we got one?
That seems reasonable.
To: rakudobug [...] perl.org
From: Alex Jakimenko <alex.jakimenko [...] gmail.com>
Date: Wed, 4 Nov 2015 03:29:37 +0200
Subject: .exitcode is 0 if .out is not closed (Proc)
Download (untitled) / with headers
text/plain 646b
Download (untitled) / with headers
text/html 1009b
First of all, let's look at the code that works:
my $p = run 'bash', '-c', 'exit 5';
say $p.exitcode;

Result:
5

Correct!

OK, now let's say I want to have the output as well:
my $p = run 'bash', '-c', 'exit 5', :out;
say 'Out: "' ~ $p.out.slurp-rest ~ '"';
say $p.exitcode;

Result:
Out: ""
0

But the exitcode is clearly not 0.

It turns out that you have to close .out in order to get it to work:
my $p = run 'bash', '-c', 'exit 5', :out;
$p.out.close;
say $p.exitcode;


I think that it's fine if the exitcode is -1 until it is closed, yet I don't understand why it does not close it automatically when I do slurp-rest (perhaps it should?).

Download (untitled) / with headers
text/plain 898b
On Wed 05 Aug 2015 11:21:05, ugexe@cpan.org wrote: Show quoted text
> On Wed Aug 05 10:32:54 2015, rob@hoelz.ro wrote:
> > See the attached script. > >
> > > It works if you close the file handle: > > perl6 -e 'my $p = shell("false", :out); $p.out.close; say $p.exitcode' > 1
There seem to be a regression: [claudio:~/tmp] 1 $ perl6 -e 'my $p = shell("false", :out); $p.out.close; say $p.exitcode' The spawned process exited unsuccessfully (exit code: 1) in block <unit> at -e line 1 [claudio:~/tmp] 1 $ perl6 -v This is Rakudo version 2015.11-768-gfb475d2 built on MoarVM version 2015.11-113-gbd56e2e implementing Perl 6.c. This mean that real exit code when non-zero can not be retrieved. Adding a CATCH block can go around the chicken-and-egg problem: exitcode can only be tested after close, but close throws an exception when exitcode is non-zero. However, this will no retrieve the real exitcode. C.
Download (untitled) / with headers
text/plain 1.2k
On Wed Jan 06 05:56:24 2016, nxadm wrote: Show quoted text
> On Wed 05 Aug 2015 11:21:05, ugexe@cpan.org wrote:
> > On Wed Aug 05 10:32:54 2015, rob@hoelz.ro wrote:
> > > See the attached script. > > >
> > > > > > It works if you close the file handle: > > > > perl6 -e 'my $p = shell("false", :out); $p.out.close; say > > $p.exitcode' > > 1
> > There seem to be a regression: > [claudio:~/tmp] 1 $ perl6 -e 'my $p = shell("false", :out); > $p.out.close; say $p.exitcode' > The spawned process exited unsuccessfully (exit code: 1) > in block <unit> at -e line 1 > > [claudio:~/tmp] 1 $ perl6 -v > This is Rakudo version 2015.11-768-gfb475d2 built on MoarVM version > 2015.11-113-gbd56e2e > implementing Perl 6.c. > > This mean that real exit code when non-zero can not be retrieved. > Adding a CATCH block can go around the chicken-and-egg problem: > exitcode can only be tested after close, but close throws an exception > when exitcode is non-zero. However, this will no retrieve the real > exitcode. > > C.
Please note that assigning the result of the close() makes it work: $ perl6 -e 'my $p = shell("false", :out); my $x = $p.out.close; say $p.exitcode' 1 $ perl6 -v This is Rakudo version 2015.12-218-gfb0a135 built on MoarVM version 2015.12-29-g8079ca5 implementing Perl 6.c.
Download (untitled) / with headers
text/plain 1.9k
The assignment fix can be simplified further: $ perl6 -e 'my $p = shell("false", :out); |$p.out.close; say $p.exitcode' 1 I would expect these 3 examples to have the same result. The actual results are `True, True, The spawned process exited unsuccessfully (exit code: 1)` `my $proc = run "perl6", "-e", "die", :out, :err; $proc.err.close; say ?$proc` `my $proc = run "perl6", "-e", "die", :out, :err; $proc.err.close; $proc.out.close; say ?$proc` `my $proc = run "perl6", "-e", "die", :out, :err; $proc.out.close; $proc.err.close; say ?$proc` On Sun Jan 24 03:15:58 2016, scullucs wrote: Show quoted text
> On Wed Jan 06 05:56:24 2016, nxadm wrote:
> > On Wed 05 Aug 2015 11:21:05, ugexe@cpan.org wrote:
> > > On Wed Aug 05 10:32:54 2015, rob@hoelz.ro wrote:
> > > > See the attached script. > > > >
> > > > > > > > > It works if you close the file handle: > > > > > > perl6 -e 'my $p = shell("false", :out); $p.out.close; say > > > $p.exitcode' > > > 1
> > > > There seem to be a regression: > > [claudio:~/tmp] 1 $ perl6 -e 'my $p = shell("false", :out); > > $p.out.close; say $p.exitcode' > > The spawned process exited unsuccessfully (exit code: 1) > > in block <unit> at -e line 1 > > > > [claudio:~/tmp] 1 $ perl6 -v > > This is Rakudo version 2015.11-768-gfb475d2 built on MoarVM version > > 2015.11-113-gbd56e2e > > implementing Perl 6.c. > > > > This mean that real exit code when non-zero can not be retrieved. > > Adding a CATCH block can go around the chicken-and-egg problem: > > exitcode can only be tested after close, but close throws an > > exception > > when exitcode is non-zero. However, this will no retrieve the real > > exitcode. > > > > C.
> > Please note that assigning the result of the close() makes it work: > $ perl6 -e 'my $p = shell("false", :out); my $x = $p.out.close; say > $p.exitcode' > 1 > > $ perl6 -v > This is Rakudo version 2015.12-218-gfb0a135 built on MoarVM version > 2015.12-29-g8079ca5 > implementing Perl 6.c.
From: brian d foy <brian.d.foy [...] gmail.com>
Subject: The Proc from run() and :out seems always to report exitcode 0
To: rakudobug [...] perl.org
Date: Thu, 26 Jan 2017 21:07:50 -0500
Download (untitled) / with headers
text/plain 2.7k
It seems that the exit value that a Proc object returns isn't always what I expect. In the calls where I specify :out, the exit code seems to always be 0. use Test; my $program = '/usr/bin/false'; # maybe yours is different ok $program.IO.e, 'program exists'; subtest { my $proc = run $program; is $proc.exitcode, 1, 'No arguments'; }, 'run with no arguments'; subtest { my $proc = run $program, :out; is $proc.exitcode, 1, 'Output specified, check exit before read'; # is it finished running? $proc.out.slurp-rest; }, 'run with :out argument, read after'; subtest { my $proc = run $program, :out; $proc.out.slurp-rest; is $proc.exitcode, 1, 'Output, check exit after read'; }, 'run with :out argument, read first'; subtest { my $null = $*SPEC.devnull.IO.open; # the program shouldn't compile and perl6 should return 1 my $proc = run $*EXECUTABLE, '-c', $program, :out, :err($null); $proc.out.slurp-rest; is $proc.exitcode, 1, 'Output, check exit after read'; }, 'compile check, read first'; done-testing(); And, the output: ok 1 - program exists ok 1 - No arguments 1..1 ok 2 - run with no arguments not ok 1 - Output specified, check exit before read 1..1 not ok 3 - run with :out argument, read after not ok 1 - Output, check exit after read 1..1 not ok 4 - run with :out argument, read first not ok 1 - Output, check exit after read 1..1 not ok 5 - run with :out argument, read first 1..5 # Failed test 'Output specified, check exit before read' # at /Users/brian/Desktop/false.p6 line 18 # expected: '1' # got: '0' # Looks like you failed 1 test of 1 # Failed test 'run with :out argument, read after' # at /Users/brian/Desktop/false.p6 line 16 # Failed test 'Output, check exit after read' # at /Users/brian/Desktop/false.p6 line 25 # expected: '1' # got: '0' # Looks like you failed 1 test of 1 # Failed test 'run with :out argument, read first' # at /Users/brian/Desktop/false.p6 line 22 # Failed test 'Output, check exit after read' # at /Users/brian/Desktop/false.p6 line 33 # expected: '1' # got: '0' # Looks like you failed 1 test of 1 # Failed test 'run with :out argument, read first' # at /Users/brian/Desktop/false.p6 line 28 # Looks like you failed 3 tests of 5 The details: $ perl6 -v && uname -a This is Rakudo version 2016.11 built on MoarVM version 2016.11 implementing Perl 6.c. Darwin macpro.local 14.5.0 Darwin Kernel Version 14.5.0
Dup of 125757

On 2017-01-26 18:08:59, comdog wrote:
Show quoted text
> It seems that the exit value that a Proc object returns isn't
> always what I expect. In the calls where I specify :out, the
> exit code seems to always be 0.
>
> use Test;
>
> my $program = '/usr/bin/false'; # maybe yours is different
>
> ok $program.IO.e, 'program exists';
>
> subtest {
> my $proc = run $program;
> is $proc.exitcode, 1, 'No arguments';
> }, 'run with no arguments';
>
> subtest {
> my $proc = run $program, :out;
> is $proc.exitcode, 1, 'Output specified, check exit before
> read'; # is it finished running?
> $proc.out.slurp-rest;
> }, 'run with :out argument, read after';
>
> subtest {
> my $proc = run $program, :out;
> $proc.out.slurp-rest;
> is $proc.exitcode, 1, 'Output, check exit after read';
> }, 'run with :out argument, read first';
>
> subtest {
> my $null = $*SPEC.devnull.IO.open;
> # the program shouldn't compile and perl6 should return 1
> my $proc = run $*EXECUTABLE, '-c', $program, :out, :err($null);
> $proc.out.slurp-rest;
> is $proc.exitcode, 1, 'Output, check exit after read';
> }, 'compile check, read first';
>
> done-testing();
>
> And, the output:
>
> ok 1 - program exists
> ok 1 - No arguments
> 1..1
> ok 2 - run with no arguments
> not ok 1 - Output specified, check exit before read
> 1..1
> not ok 3 - run with :out argument, read after
> not ok 1 - Output, check exit after read
> 1..1
> not ok 4 - run with :out argument, read first
> not ok 1 - Output, check exit after read
> 1..1
> not ok 5 - run with :out argument, read first
> 1..5
>
> # Failed test 'Output specified, check exit before read'
> # at /Users/brian/Desktop/false.p6 line 18
> # expected: '1'
> # got: '0'
> # Looks like you failed 1 test of 1
>
> # Failed test 'run with :out argument, read after'
> # at /Users/brian/Desktop/false.p6 line 16
>
> # Failed test 'Output, check exit after read'
> # at /Users/brian/Desktop/false.p6 line 25
> # expected: '1'
> # got: '0'
> # Looks like you failed 1 test of 1
>
> # Failed test 'run with :out argument, read first'
> # at /Users/brian/Desktop/false.p6 line 22
>
> # Failed test 'Output, check exit after read'
> # at /Users/brian/Desktop/false.p6 line 33
> # expected: '1'
> # got: '0'
> # Looks like you failed 1 test of 1
>
> # Failed test 'run with :out argument, read first'
> # at /Users/brian/Desktop/false.p6 line 28
> # Looks like you failed 3 tests of 5
>
> The details:
>
> $ perl6 -v && uname -a
> This is Rakudo version 2016.11 built on MoarVM version 2016.11
> implementing Perl 6.c.
> Darwin macpro.local 14.5.0 Darwin Kernel Version 14.5.0


Download (untitled) / with headers
text/plain 1.8k
Hey Brian, here's a version of your test code that works: use Test; my $program = '/usr/bin/false'; # maybe yours is different ok $program.IO.e, 'program exists'; subtest { my $proc = run $program; is $proc.exitcode, 1, 'No arguments'; }, 'run with no arguments'; subtest { my $proc = run $program, :out; $proc.out.slurp-rest(:close); # is it finished running? is $proc.exitcode, 1, 'Output specified, check exit before read'; }, 'run with :out argument, read after'; subtest { my $proc = run $program, :out; $proc.out.slurp-rest(:close); is $proc.exitcode, 1, 'Output, check exit after read'; }, 'run with :out argument, read first'; subtest { my $null = $*SPEC.devnull.IO.open; # the program shouldn't compile and perl6 should return 1 my $proc = run $*EXECUTABLE, '-c', $program, :out, :err($null); $proc.out.slurp-rest(:close); is $proc.exitcode, 1, 'Output, check exit after read'; }, 'compile check, read first'; done-testing(); Output: ok 1 - program exists ok 1 - No arguments 1..1 ok 2 - run with no arguments ok 1 - Output specified, check exit before read 1..1 ok 3 - run with :out argument, read after ok 1 - Output, check exit after read 1..1 ok 4 - run with :out argument, read first ok 1 - Output, check exit after read 1..1 ok 5 - compile check, read first 1..5 you need to pass :close to slurp-rest so that it closes the output pipe, otherwise your program will keep running and won't actually exit. Please note that i also re-ordered things in the second subtest. There's been discussion that running .exitcode either while the program is still running or while out/err aren't closed should throw an exception immediately.
RT-Send-CC: perl6-compiler [...] perl.org
Download (untitled) / with headers
text/plain 405b
On Thu, 18 Feb 2016 09:51:34 -0800, ugexe@cpan.org wrote: Show quoted text
> The assignment fix can be simplified further: > $ perl6 -e 'my $p = shell("false", :out); |$p.out.close; say > $p.exitcode' > 1
Or even simpler: $ perl6 -e 'my $p = shell("false", :out); $p.out.close.exitcode.say' 1 .close doesn't throw as some above suggested. It returns the Proc object and sunk Proc with non-zero exitcode throws.
This has been resolved since 2017.06


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org