Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Backticks don't give exception for nonexistant command #1396
Does not seem specific to our Java 7 backtick logic, but the Java 6 logic does at least provide the execution error as a string:
As of 1.7.12, the behavior I've observed is that the exit status is actually completely ignored. And you still get the stdout, but the stderr is completely ignored. This is identical to the MRI behavior (2.1.1), except MRI apparently lets stderr pass right through to my terminal -- the program still doesn't see that error, but at least I can see it this time.
There's still the difference with getting an ENOENT or not. I would guess what's happening here is that Ruby can just call the native C stuff like execvp(), which handles the PATH environment variable without forcing you to actually launch a shell, and that's where the ENOENT comes from. But for more complicated commands, you have to use the shell anyway:
As far as I can tell, since it's the shell reporting the error, it shows up on stderr, gets passed through to my terminal, and the program just gets an empty string. So I would guess what happens here is JRuby always uses /bin/sh (even for commands we could handle without it), and it always discards stderr, instead of letting it through to the terminal.
I'm learning that if I care about whether a command actually ran, backticks are probably a bad idea. Still, would it be useful to duplicate MRI's behavior here?
On a further note, jruby-1.7.19 still has this behavior, and while in MacOSX/Linux + JDK7/8 a non existant command returns "", the same jruby version on Windows will properly raise an exception:
The behaviour in both environments should be consistent (and ideally also between JRuby and MRI).
referenced this issue
May 7, 2015
So this is a bit gnarly. The logic for ` lives in process_manager.rb and is implemented in Ruby using Java integration. It calls into LaunchConfig to check if we should use sh for the backtick, which returns true unconditionally when not running on Windows. That causes it to use sh, which doesn't find the command, but stderr appears not to be hooked up.
Note that MRI is a bit inconsistent here too...if you have a bad command with any shell characters nearby, it will switch to running with sh and NOT raise any error: