-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
What should Process(args, shell: true) do on Windows? #9030
Comments
Where the compiler use the shell interpreter, it can be refactored not to use it.
|
I think that passing arguments to As @j8r said though, the compiler can be modified to not use the shell and instead construct the args array without |
The reason that people actually use My main plan now is to not support only And Because on Windows the thing you pass to a process is a single string with all args, possibly quoted, unlike on Unix where you pass an array. If you disagree that there should be no support for implicitly invoking |
I should also note that for running commands with the |
Passing a single argument in args with
|
Oh no no, it shouldn't. |
Ah I think you mean |
The topic is likely wider than only just On thing is for differentiate commands and arguments is separating them with a Line 403 in 7e2e840
|
@j8r Sure, the topic is wide, but the behavior of the other aspects is obvious, and already implemented for a future PR. I don't think |
Maybe, I don't know how if Windows disambiguate command and arguments? |
We could do something similar as It may makes no sense to have both |
@j8r indeed. That is implemented in https://github.com/oprypin/crystal/compare/winapi |
Not invoking |
POSIX has "the shell" (you just set a text file to be executable and the shell will be called) and Windows doesn't have "the shell". |
If we anticipate |
I think it's perfectly sensible to use |
Not sure if this is an unexpected behavior or it's by design ;-) error: Unhandled exception: Error executing process: 'npm -v': The system cannot find the file specified. (File::NotFoundError)from E:\scoop\global\apps\crystal\current\src\crystal\system\win32\process.cr:223 in 'spawn' status = Process.run(command: "npm -v", shell: true)
p! status.success? okstatus = Process.run(command: "cmd", args: ["-c","npm -v"])
p! status.success?
# or
status = Process.run(command: "powershell", args: ["-NoProfile", "-NoLogo", "npm -v"])
p! status.success? |
These two are equivalent and wrong because indeed rather than telling Process.run("cmd", args: ["/c","npm -v"])
Process.run("cmd /c \"npm -v\"", shell: true) The only correct way is Process.run("cmd /c npm -v", shell: true) |
I misunderstood that shell:true will automatically add |
Let's examine the current implementation of
Process.new(command, args, shell: true)
.crystal/src/process.cr
Lines 387 to 405 in 4401e90
For context, this allows you to pass a free-form command but also safely pass a list of arguments to it. E.g.
It relies on POSIX shell to expand the arguments for it, which is a nice implementation, however, this kind of puts us in an uncertain situation for also supporting Windows.
The problem is that the literal text
"${@}"
must be present in the specified command, butSo I think the best way forward needs to avoid relying on this specific character sequence. But I don't know how to do it without losing functionality.
And in general, what is
Process.run(command, args, shell: true)
even supposed to do on Windows?If we disregard the desire to avoid hacks, sure, I could just do a literal replacement from
"${@}"
toargs
, safely quoted and joined. But hm.....Should this just raise "not implemented"? Maybe.
But the compiler does rely on this feature in this crucial code:
crystal/src/compiler/crystal/compiler.cr
Line 358 in 0bb3fe9
crystal/src/compiler/crystal/compiler.cr
Line 395 in 0bb3fe9
Side note: how Python does this:
So it has the equivalent functionality but it's never advertised as anything special, the POSIX shell just happens to do this if multiple args are passed.
And on Windows, ... Python just doesn't do anything useful. I guess it runs
cmd /C "command" "arg1" "arg2"
I also quite dislike that in Crystal the
command
andargs
are separate; usually it's more natural to have thecommand
be just the first item ofargs
. Yes, it's another topic, but note that it could make some things make more sense here.The text was updated successfully, but these errors were encountered: