Quotation in System.Process.system for Windows
Wagnerdm writes: I had a bit of fun recently tracking down quoting issues with the "system
" command in Windows. For the examples below, I'll consistently use "Windows>
" as the beginning of some text sent to the Windows command prompt cmd.exe, and use "GHC>
" as the beginning of some text sent to a ghci session running in cmd.exe with System.Cmd
imported.
The situation is this: I want to hand off a command line which has both a possibly-quoted command name and a (definitely) quoted argument. For concreteness, let's use "more" as the command and "foo.txt" as the argument, so that you can follow along at home on your favorite Windows system.
Windows> echo foo > foo.txt
Windows> "more" "foo.txt"
foo
All good so far. But:
GHC> system "\"more\" \"foo.txt\""
'more" "foo.txt' is not recognized as an internal or external command, operable program or batch file.
ExitFailure 1
After some digging, I discovered that system is shipping out to cmd /c, and indeed:
Windows> cmd /c "more" "foo.txt"
'more" "foo.txt' is not recognized as an internal or external command, operable program or batch file.
I don't know what the *right* fix is. However, after a bit of playing around, I discovered the following:
Windows> cmd /c ""more" "foo.txt""
foo
GHC> system "\"\"more\" \"foo.txt\"\""
foo
ExitSuccess
Wrapping commands with an extra pair of double-quotes this way seemed to give behavior matching the bare cmd.exe for all the examples I could think of, even ones I thought it would break. For example:
GHC> system "\"more foo.txt\""
foo
ExitSuccess
If this turns out to be the right thing to do, it's pretty easy to implement. In the commandToProcess
function, at libraries/process/System/Process/Internals.hs:455
, the change is just
- return (cmd, translate cmd ++ "/c " ++ string)
+ return (cmd, translate cmd ++ "/c \"" ++ string ++ "\"")
(And in any case, the examples above should answer this amusing comment, immediately following those lines:
-- We don't want to put the cmd into a single
-- argument, because cmd.exe will not try to split it up. Instead,
-- we just tack the command on the end of the cmd.exe command line,
-- which partly works. There seem to be some quoting issues, but
-- I don't have the energy to find+fix them right now (ToDo). --SDM
-- (later) Now I don't know what the above comment means. sigh.
Later, Brandon comments: What that comment means is that how CMD.EXE handles spaces is Windows-version-dependent. On the other hand, I think it's mostly consistent between XP and Windows 7 --- and I feel sorry for anyone forced to use an older version.
Trac metadata
Trac field | Value |
---|---|
Version | 7.0.4 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | Unknown/Multiple |
Architecture |