System.Process.system in Windows

wagnerdm at seas.upenn.edu wagnerdm at seas.upenn.edu
Thu Aug 4 00:57:44 CEST 2011


Hello all,

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.

=)

~d



More information about the Glasgow-haskell-users mailing list