Re: Windows 2000 and XP and exec and double quotes

From: Benjamin Riefenstahl (Benjamin.Riefenstahl_at_epost.de)
Date: 01/29/04


Date: Thu, 29 Jan 2004 14:01:26 +0100

Hi David,

David Gravereaux <davygrvy@pobox.com> writes:
> D:\tcl_workspace\tcl_head_stock\win>release\tclsh85
> % exec cmd.exe /c echo \"hello\"
> "hello"
> % exec cmd.exe /c echo {"hello"}
> "hello"
> %

I'm not sure I agree without some more discussion.

"cmd /c echo" just outputs it's commandline, so it's not very typical,
but it is of course a good tool for diagnosis.

We also know that a number of the other Windows console tools parse
their command-line themself and come up with idiosyncratic
interpretations.

A typical consiole program OTOH will use the C runtime and the
argc/argv that this provides.

In the light of these differences, I think that the most versatile
mode of operation is not to try to escape the [exec] parameters. Just
[concat] them and pass them on. That gives the programmer the means
to implement what is needed in every case. It is not really
compatible with the Unix [exec], though.

So maybe we need two modes for [exec] (or even two different
commands). One would do as I say above, pass the command line on
as-is, and the other one would do a typical C runtime style escaping.

The remaining question is, what is a "typical" C runtime style
escaping? I did a test (see below) and it looks like protecting
spaces (and possibly other characters) by encasing the whole string in
quotes and escaping quotes in parameters with backslashes is a method
that works consistently with the compilers tested. Note that
backslashes have *only* special meaning before quotes, so filenames
are not affected by this scheme. Also, parameters with
backslash-escaped quotes should be encased in quotes as a whole.

So for the C runtime case the current [exec] implementation may
actually be right, except that it could be improved to add quotes in
cases like

  % exec exec cmd.exe /c echo {hi"there}
  hi\"there

I think we also do need the no-changes variant though, to be able to
control the escape rules for non-typical cases.

Test argv implementation in the most common runtimes
----------------------------------------------------

I wrote a trivial C program and compiled it with VC++ 5.0, Borland 5.5
(the downloadable version) and Cygwin:

 #include <stdio.h>

 int main( int argc, char ** argv )
 {
        int i;
        for( i=1; i<argc; ++i ) {
                printf("argv[%d] = >>%s<<\n", i, argv[i]);
        }
        return 0;
 }

The Microsoft runtime accepts backslashes and doubled quotes inside
quotes to actually pass quotes to the program.

  c:\tmp> vc50-argv "hello" ""hello"" """hello""" "\"hello\"" "he\nllo"
  argv[1] = >>hello<<
  argv[2] = >>hello<<
  argv[3] = >>"hello"<<
  argv[4] = >>"hello"<<
  argv[5] = >>he\nllo<<

It does seem to get confused with the doubled quotes syntax though

  c:\tmp> vc50-argv "he""llo" hi
  argv[1] = >>he"llo hi<<

The Borland (5.5) runtime accepts backslashes, but otherwise strips
*all* unescaped quotes.

  c:\tmp> bc55-argv "hello" ""hello"" """hello""" "\"hello\"" "he\nllo"
  argv[1] = >>hello<<
  argv[2] = >>hello<<
  argv[3] = >>hello<<
  argv[4] = >>"hello"<<
  argv[5] = >>he\nllo<<

Cygwin basically works the same as the MS runtime, but has some
different interpretation when it encounters backslashes outside of
quote encasings:

  c:\tmp> cygwin-argv "hello" ""hello"" """hello""" "\"hello\"" "he\nllo"
  argv[1] = >>hello<<
  argv[2] = >>hello<<
  argv[3] = >>"hello"<<
  argv[4] = >>"hello"<<
  argv[5] = >>he\nllo<<

  c:\tmp> cygwin-argv \"hello\" "he\nllo"
  argv[1] = >>\hello" henllo<<

  c:\tmp> cygwin-argv "he""llo" hi
  argv[1] = >>he"llo<<
  argv[2] = >>hi<<

----


Relevant Pages

  • Re: Windows 2000 and XP and exec and double quotes
    ... arguments to exec. ... exec wish test1.tcl $cmd ... > quotes and escaping quotes in parameters with backslashes is a method ...
    (comp.lang.tcl)
  • Re: cmd-window startup
    ... The commandline for programs invoked by double-clicking on the file in ... Windows Explorer will contain a fully qualified path, ... double quotes. ...
    (comp.lang.asm.x86)
  • Re: cmd-window startup
    ... The commandline for programs invoked by double-clicking on the file in ... Windows Explorer will contain a fully qualified path, ... double quotes. ...
    (comp.lang.asm.x86)
  • Re: get only filenames and not directory names under a specific path.
    ... > I'm guess maybe it's must do that when it's double quotes. ... but with two exceptions: the escape character itself ... the string delimiter can also be escaped to allow embedded single quotes, ... means that a path with a trailing backslash needs two backslashes there to avoid ...
    (perl.beginners)
  • Re: Windows 2000 and XP and exec and double quotes
    ... On the Tcl level the literal constants ... These two are indeed where you hit the problem in Windows [exec]. ... Note that, as I said before, quotes can not occur in Windows filenames ... Does ntbackup explicitly want quotes? ...
    (comp.lang.tcl)