Open dazuma opened 2 years ago
Thanks for the report.
The semantics are more complicated (i.e., the docs are wrong), a single argument String can run without an extra shell, this is the behavior and optimization of CRuby, and TruffleRuby tries to replicate it.
So in CRuby there is some logic which specifically checks for shell builtins like exit
, which we need to replicate in TruffleRuby as well: https://github.com/ruby/ruby/blob/v2_7_2/process.c#L2449-L2530
If you pass a single string argument to
Process.spawn
, it should interpret it as a command line to pass to the standard shell (see e.g. the documentation at https://ruby-doc.org/core-2.7.5/Process.html#method-c-spawn). Only if you pass multiple arguments, or if the first argument is an array, shouldProcess.spawn
bypass the shell and attempt to spawn the process directly.This is the behavior of MRI (versions 2.7.5 and 3.1.0 tested). However, TruffleRuby 21.3.0 sometimes appears to attempt to parse the command line and spawn it directly. without using a shell.
Example:
In MRI (on a MacOS X machine), the above succeeds, spawning a shell process that exits with a 0 status code. However, on TruffleRuby, it raises because it can't find a binary called "exit", apparently not recognizing it as a shell built-in:
It looks like
Kernel#system
behaves similarly. Consider the following:On MRI, this prints
0
. On TruffleRuby, this incorrectly prints127
.Interestingly, if the command includes multiple processes, shell pipelines, or other features, it runs correctly. The two examples below do behave correctly on TruffleRuby. It makes me wonder if there's an optimization gone awry.