haskell / haskell/process

Quotation in System.Process.system for Windows

Open
#51 6 comments 1 reaction 0 assignees View on GitHub
Dominant language
Haskell
Stars
91
Forks
91
PR merge metrics
No merged PRs in 30d

Description

Moved from https://ghc.haskell.org/trac/ghc/ticket/5376:

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.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.