Feature #16791
openShortcut for Process::Status.exitstatus
Added by 0x81000000 (/ /) over 4 years ago. Updated over 4 years ago.
Description
[Updated]
s = `csc x.cs`.sub(/.*?\n\n/m, '')
puts s if s != ''; exit $?.exitstatus if $?.exitstatus > 0
system 'mono x.exe'; exit $?.exitstatus
class Process::Status
alias :es :exitstatus
end
s = `csc x.cs`.sub(/.*?\n\n/m, '')
puts s if s != ''; exit $?.es if $?.es > 0
system 'mono x.exe'; exit $?.es
Updated by shevegen (Robert A. Heiler) over 4 years ago
This is not a good feature request, IMO.
There is not really any explanation as to what the idea is about. Why is
p pid and s existatus suddenly? And why should that be common if one
can already extend these classes as-is? What is the rationale for the
feature request? Even IF this were accepted as-is, I think there should
be a fair description of the issue request, so that other people can
understand what is going on at a later point in time. This would be
more in line what is often encouraged for people to do by the ruby
core team, in that they should describe (possible) use cases, benefits
and drawbacks objectively.
Updated by 0x81000000 (/ /) over 4 years ago
- Description updated (diff)
- Subject changed from Shortcuts for attributes of Process::Status to Shortcut for Process::Status.exitstatus
Updated by Dan0042 (Daniel DeLorme) over 4 years ago
Those short aliases are definitely a bad idea but I understand the OP's frustration with $?
because it's different from the shell's $?
. Process::Status
has several methods that I'm sure can be useful in various circumstances, but the only one I've ever needed was exitstatus
. It's a bit irritating when you have to write the verbose $?.exitstatus
(get the exit status of the exit status?) instead of the shorter and more natural $?
, especially for the common case of exit $?
Updated by nobu (Nobuyoshi Nakada) over 4 years ago
It is not a good idea to compare exitstatus
with 0 from the point of portability.
I'd recommend to use Process::Status#success?
.
Also if the exit code value is not important but succeeded or failed is just needed, exit $?.success?
would be enough.
Even exec
works better than system
& exit
, unless you need some clean-ups.
Updated by 0x81000000 (/ /) over 4 years ago
nobu (Nobuyoshi Nakada) wrote in #note-4:
Even
exec
works better thansystem
&exit
, unless you need some clean-ups.
You're right. What can you say about this 'vararg require':
module Kernel
alias :require_1 :require
def require p, *a
return require_1 p if a.empty?
a.unshift p
a.map { | s | require_1 s }
end
end
Could this break backward compatibility?
Updated by Dan0042 (Daniel DeLorme) over 4 years ago
nobu (Nobuyoshi Nakada) wrote in #note-4:
It is not a good idea to compare
exitstatus
with 0 from the point of portability.
Can I ask why that is? 0 is success and non-0 is failure; I don't know of any system where things are different. What is the portability issue?
Even
exec
works better thansystem
&exit
, unless you need some clean-ups.
exec
only works as a tail-call at the end of the script. Most of the time it's not applicable:
system(cmd1) or exit($?.exitstatus)
system(cmd2) or exit($?.exitstatus)
system(cmd3) or exit($?.exitstatus)
Although thanks to your comment I've realized that exitstatus is nil if the process exited because of a signal. That means the code above is equivalent to exit(0)
if the command failed because of $?.signaled?
:-(
I guess I'm better off sticking with system(cmd1) or abort
Updated by nobu (Nobuyoshi Nakada) over 4 years ago
Dan0042 (Daniel DeLorme) wrote in #note-6:
nobu (Nobuyoshi Nakada) wrote in #note-4:
It is not a good idea to compare
exitstatus
with 0 from the point of portability.Can I ask why that is? 0 is success and non-0 is failure; I don't know of any system where things are different. What is the portability issue?
I don't know such systems actually too, just only the rationale of EXIT_SUCCESS
and EXIT_FAILURE
in the C standard.
Although thanks to your comment I've realized that exitstatus is nil if the process exited because of a signal. That means the code above is equivalent to
exit(0)
if the command failed because of$?.signaled?
:-(
That executes exit(nil)
and results in TypeError
.
I guess I'm better off sticking with
system(cmd1) or abort
Yes, it's a good alternative.
It may be acceptable to let exit
accept a SystemExit
instance though.
Updated by Eregon (Benoit Daloze) over 4 years ago
nobu (Nobuyoshi Nakada) wrote in #note-7:
It may be acceptable to let
exit
accept aSystemExit
instance though.
I think that would be useful.
I'd guess it would behave as something like:
# useful if terminated by a signal:
exit(status) =>
exit(status.exitstatus || status.termsig || status.stopsig || 1)
# or maybe the simpler
exit(status) =>
exit(status.exitstatus || 1)
# but then no information if terminated by signal, which is bad
It's probably even better to raise a SignalException
on exit(status)
if status.signaled?
, that way the information is completely forwarded to the parent process.
Updated by 0x81000000 (/ /) over 4 years ago
Dan0042 (Daniel DeLorme) wrote in #note-6:
exec
only works as a tail-call at the end of the script. Most of the time it's not applicable:system(cmd1) or exit($?.exitstatus) system(cmd2) or exit($?.exitstatus) system(cmd3) or exit($?.exitstatus)
exec 'cmd1 && cmd2 && cmd3'
Updated by Dan0042 (Daniel DeLorme) over 4 years ago
nobu (Nobuyoshi Nakada) wrote in #note-7:
That executes
exit(nil)
and results inTypeError
.
Ah, interesting, I was testing in irb where exit(nil)
was equivalent to exit(0)
Eregon (Benoit Daloze) wrote in #note-8:
nobu (Nobuyoshi Nakada) wrote in #note-7:
It may be acceptable to let
exit
accept aSystemExit
instance though.I think that would be useful.
I'd guess it would behave as something like:# useful if terminated by a signal: exit(status) => exit(status.exitstatus || status.termsig || status.stopsig || 1)
Are we talking about SystemExit or Process::Status? I don't understand how SystemExit would work or be useful here, but I love the idea of exit($?)
serving as a shortcut for that long expression. Actually it seems that a signal-terminated process has an exit status of 128+signal in the shell. So exit($?)
could be a shortcut for exit($?.exitstatus || 128 + ($?.termsig || $?.stopsig || 0))
. I think there's a real win in having the easier to use shorter expression be more robust/correct than the longer exit($?.exitstatus)
It's probably even better to raise a
SignalException
onexit(status)
ifstatus.signaled?
, that way the information is completely forwarded to the parent process.
Maybe... but honestly I'm not sure it would be architecturally correct for the process to fake being terminated by a signal. Also what would happen if the process was catching the signal that caused the subprocess to terminate? It seems simpler and less edge-case-prone to let the exit
method do a regular exit.
trap("PIPE"){ }
system("cmd1") or #terminated by PIPE
exit($?) #does not exit because of trap?
#we reach here even though cmd1 failed?