From: Eli Z. <el...@gn...> - 2014-06-25 13:51:26
|
> Date: Wed, 25 Jun 2014 01:05:55 +0100 > From: Keith Marshall <kei...@us...> > > On 24/06/14 23:11, Yuri Kanivetsky wrote: > > If I understand you correctly, using single quotes is no better than using > > double quotes here. Both commands: > > > > $ cmd //c '"cmd" /c echo test' > > $ cmd //c "\"cmd\" /c echo test" > > > > produce the same command line: > > > > c:\Windows\system32\cmd.exe /c "\"cmd\" /c echo test" > > Correct. The inner pair of double quotes are literal; according to both > http://msdn.microsoft.com/en-us/library/a1y7w461.aspx and > http://msdn.microsoft.com/en-us/library/17w5ykft.aspx Those URLs describe what the standard C/C++ library startup code does to convert the command line into the argv[] array. But a program doesn't have to use that startup code, it can provide its own (and in fact, MinGW 4.x actually does). It can even (gasp!) not be a C/C++ program. IOW, these are in no way Windows-wide requirements, they are limited to programs that use standard C/C++ libraries for their startup code. In particular, those URLs are not applicable to how cmd.exe treats quoted command arguments. > > And they doesn't do what they are supposed to do. The point here is to pass > > the following command line to the process: > > > > c:\Windows\system32\cmd.exe /c ""cmd" /c echo test" > > Well, applying the parsing logic from each of those MSDN references, > that is identically equivalent to > > c:\Windows\system32\cmd.exe /c cmd" /c echo test" > > because the first pair of quotes delimit an empty string. That's not how cmd.exe handles that command line. The definition of how cmd.exe does that is part of what "cmd /?" displays; here's the relevant part: If /C or /K is specified, then the remainder of the command line after the switch is processed as a command line, where the following logic is used to process quote (") characters: 1. If all of the following conditions are met, then quote characters on the command line are preserved: - no /S switch - exactly two quote characters - no special characters between the two quote characters, where special is one of: &<>()@^| - there are one or more whitespace characters between the the two quote characters - the string between the two quote characters is the name of an executable file. 2. Otherwise, old behavior is to see if the first character is a quote character and if so, strip the leading character and remove the last quote character on the command line, preserving any text after the last quote character. Item 1 is lawyer-speak, but if you read it carefully several time, you will understand that it almost never happens. It is only here for the special case that the program you invoke has whitespace in its file name. So the interesting part is item 2, which describes "old behavior" (a hint to why cmd.exe does what it does), and it boils down to a very simple rule of quoting command lines to be passed to cmd.exe: compose a command line you would type at the shell prompt, with quotes wherever you need them, then simply enclose the whole command-line string in an extra pair of quotes. That's it! IOW, the OP is correct: MSYS ought to have special support for invoking cmd.exe by either automatically enclosing cmd.exe commands in quotes, or at least allowing users some fire escape whereby they could achieve that effect. > > AFAIR, some programs, amongst which are cmd, start, hstart, treat their > > command line specially. When given things like `""cmd" /c echo test"`, they > > just ignore the outer quotes or treat the whole thing as one big quoted > > argument. > > Then such programs violate Microsoft's own parsing conventions No, they don't; see above. But even if they did, cmd.exe is not some obscure or "arcane" program. So it is IMO meaningless to claim that it violates some conventions; a program that invokes a stock Windows shell without honoring how that shell handles quoted commands is simply a broken program. You cannot have a useful Windows program that invokes other programs, if it doesn't know how to invoke cmd.exe correctly and reliably. > MSYS has been developed to interoperate with applications which do > conform to those conventions, and accordingly DTRT. This means, plain and simple, that MSYS is inappropriate for invoking cmd.exe. Which is not a catastrophe, at least not for people who, like me, limit MSYS usage to configuring and building Posix software, where cmd.exe does not need to be invoked. But other MinGW users, who do like using MSYS in routine operation of their Windows boxes, might not be pleased by this conclusion. It would be nice if MSYS developers added proper support for passing quoted commands to cmd.exe. |