Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shell().exitcode is always 0 when :out is used #4456

Open
p6rt opened this issue Aug 5, 2015 · 17 comments
Open

shell().exitcode is always 0 when :out is used #4456

p6rt opened this issue Aug 5, 2015 · 17 comments

Comments

@p6rt
Copy link

@p6rt p6rt commented Aug 5, 2015

Migrated from rt.perl.org#125757 (status was 'open')

Searchable as RT125757$

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Aug 5, 2015

From @hoelzro

See the attached script.

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Aug 5, 2015

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Aug 5, 2015

From @hoelzro

On 2015-08-05 10​:32​:54, rob@​hoelz.ro wrote​:

See the attached script.

Same goes for run().

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Aug 5, 2015

From @ugexe

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

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Aug 6, 2015

From @FROGGS

Shall we attempt to make the exitcode (Int) until we got one?

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Aug 6, 2015

The RT System itself - Status changed from 'new' to 'open'

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Aug 6, 2015

From @hoelzro

On 2015-08-05 23​:20​:24, FROGGS.de wrote​:

Shall we attempt to make the exitcode (Int) until we got one?

That seems reasonable.

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Nov 4, 2015

From @AlexDaniel

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?).

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Jan 6, 2016

From nxadm@apt-get.be

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.

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Jan 24, 2016

From @lucs

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.

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Feb 18, 2016

From @ugexe

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​:

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.

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Jan 27, 2017

From @briandfoy

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

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Jan 27, 2017

From @AlexDaniel

Dup of 125757

On 2017-01-26 18​:08​:59, comdog wrote​:

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

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Jan 27, 2017

The RT System itself - Status changed from 'new' to 'open'

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Feb 4, 2017

From @timo

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.

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Feb 14, 2017

From @zoffixznet

On Thu, 18 Feb 2016 09​:51​:34 -0800, ugexe@​cpan.org wrote​:

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.

@p6rt

This comment has been minimized.

Copy link
Author

@p6rt p6rt commented Jul 13, 2017

From @ugexe

This has been resolved since 2017.06

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.