This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: syntax for Cygwin bash invoking Win apps

>On Tue, Sep 8, 2009 at 11:30 PM, Ziser, Jesse wrote:
>> Hello list,
>> When I type a command in bash to invoke a Windows application (like cmd.exe,
>> for example), I can't seem to find a pattern in the Windows command line that
>> actually gets executed.  Ordinary bash syntax does not seem to apply in
>> general when the command is a Windows app, but rather, sometimes special
>> characters are interpreted in a bash-like way, and sometimes not.  So, I'm
>> wondering what determines whether a quote mark or something gets interpreted
>> or passed on.
>I can't contend to be an expert on cmd.exe escaping, but I'll take the first
>swing...  And the MS docs found at [1] will probably be more useful

Heh, that's OK, I don't need any help with cmd.exe escaping.  cmd.exe generally doesn't do any quote or escape replacement (except in a few rare cases).  In Windows, the command itself is usually responsible for that sort of thing.

>> Here are some examples:
>> $ cmd /c echo "/?"
>> Displays messages, or turns command-echoing on or off.
>>   ECHO [ON | OFF]
>>   ECHO [message]
>> Type ECHO without parameters to display the current echo setting.
>Falls under the expansion conditions mentioned at the "processing
>quotation marks" section of the cmd manual; so it expands to run the
>command 'echo' with the argument '/?'

Nope.  The Windows "echo" does not remove quotes.  In this case, bash is removing the quotes.  This is a bash command line.  Also, cmd /c does not remove quotes, except when they are around the whole entire argument to cmd /c, which is not the case here.  To see this, try this at the Windows command prompt:

> cmd /c echo "hi"

>> # OK, so I'm getting the Windows echo, not the bash echo.  Good.
>> # Moving on...
>> $ cmd /c echo abc
>> abc
>No quoting...
>> $ cmd /c echo "abc"
>> abc
>One set of quotes that is stripped, per the DOS rules ("If the previous
>conditions are not met, string is processed by examining the first
>character to verify whether or not it is an opening quotation mark. If
>the first character is an opening quotation mark, it is stripped along
>with the closing quotation mark.  Any text following the closing
>quotation marks is preserved.").  Granted, that rule doesn't make a lot
>of sense, but that's why we all prefer UNIX...  >_>

Nope.  The rule you just quoted specifically says it looks at the first character of the string to determine whether it is a quotation mark.  The first character of the string here is the letter "e".  Besides, this is a bash command line, so bash should be the one removing the quotes.

>> $ cmd /c echo "\"abc\""
>> "\"abc\""
>> # Wahhh?!
>Again, a weird MS quoting behavior.  The "previous conditions" mentioned
>above include "you use exactly one set of quotation marks".  Here, you
>didn't, so cmd is nice enough to not strip anything for you.

But the above is a bash command.  Bash should remove the quotes and replace the escape sequences with literal quotes, shouldn't it?  But I do agree that if, for some reason (a reason I want to know), bash knew not to do quote replacement on this command, cmd.exe would produce exactly the output shown for this case.

>> Anyone who knows the explanation would make me very grateful.  I've tried
>> this with other Windows apps too, and the same weirdness seems to occur.
>> On a related note, I've noticed what appears to be an automatic sort of
>> half-bash invocation (but not quite?) or something when I run Cygwin commands
>> from cmd.exe.  For example,
>>> c:\cygwin\bin\echo hi
>> hi
>Nothing bash about this... Calling c:/cygwin/bin/echo.exe with the
>single argument 'hi'
>>> c:\cygwin\bin\echo "hi"
>> hi
>Nor this; it expands to exactly the same call

Nope.  To my knowledge, neither nor cmd.exe ever does quote removal on any command typed at the command prompt.  That should be passing literal quotation marks to echo.exe.

>>> c:\cygwin\bin\echo "\"hi\""
>> "hi"
>This one I'm not sure about, but I think the reason is that the above
>crazy quoting rules only apply to "cmd /c" and "cmd /k", and that this
>undergoes a different sort of escaping where it is transformed to a call
>to echo.exe with just the argument '"hi"'.  Should be easy enough to
>test by using DOS echo instead of cygwin echo, but I don't have access
>to Cygwin ATM.

As I said above, using the Windows echo at the Windows command prompt does not do any quote removal whatsoever, and it most CERTAINLY does not treat backslash as an escape character!  Backslashes are an essential piece of the filesystem syntax in Windows!

>>> c:\cygwin\bin\echo *
>> myfile myotherfile yetanotherfile ...
>Nothing bash-related about this, either.  cmd.exe expanded the * to
>a list of files, just like you'd expect.

Why on Earth would you expect that?!  What cmd.exe are you using?  Are you using PowerShell or something?

>"echo *" should work fine in
>DOS, even without any cygwin tools, so this just expanded to a call to
>"echo.exe" with 3 arguments, "myfile", "otherfile", and

Maybe your DOS, but not mine!  Did you really try it and get that result under DOS?  I've been using DOS since v3.2 and have never seen behavior like that.

>> And yet...
>>> c:\cygwin\bin\echo $PATH
>> $PATH
>This one should make the most sense of all.  cmd.exe doesn't expand
>$ENVVAR (unix syntax for an environment variable), it expands %ENVVAR%
>(dos syntax), so naturally $PATH is passed straight through.  In
>a normal unix environment, $PATH would be expanded by a shell like bash
>or csh, which you've left out of that interaction; /bin/echo certainly
>isn't expected to check its arguments for possible environment variables
>and expand them itself.

That, I would expect, but given the other things that appear to happen, this behavior seems inconsistent.


Problem reports:
Unsubscribe info:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]