Re: Windows 2000 and XP and exec and double quotes

From: Ramon Ribó (ramsan_at_cimne.upc.es)
Date: 01/29/04


Date: Thu, 29 Jan 2004 14:04:59 GMT


    Hello,

    I agree with David that current TCL is broken in Windows when sending
arguments to exec. Try the following:

----------------------------
file test1.tcl

eval [lindex $argv 0]
---------------------------
file test2.tcl

set cmd {
  proc hello { } {
     tk_messageBox -message "hello world"
  }
  hello
}
exec wish test1.tcl $cmd
----------------------------

and see the results. If you try the same on UNIX, it works.

   Best regards,

-- 
Ramon Ribó
http://gatxan.cimne.upc.es/ramsan
"Benjamin Riefenstahl" <Benjamin.Riefenstahl@epost.de> escribió en el
mensaje news:m37jzalxi1.fsf@seneca.benny.turtle-trading.net...
> 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
    ... 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)
  • Re: SQL password complexity
    ... a semicolon is an optional *statement* delimiter. ... EXEC sp_password NULL, 'new;password', 'DevLogin' ... the value isn't properly enclosed in single quotes: ... SQL Server MVP ...
    (microsoft.public.sqlserver.security)
  • Re: Long file name problem
    ... Jerold Schulman wrote: ... We cannot execute programs with long file names unless we wrap them in quotes. ... This is starting to cause some problem with programs on the system, as they don't wrap their commands in quotes by default. ... I had to do the same thing when install Back-up Exec. ...
    (microsoft.public.win2000.file_system)
  • Re: Windows 2000 and XP and exec and double quotes
    ... "cmd /c echo" just outputs it's commandline, so it's not very typical, ... mode of operation is not to try to escape the [exec] parameters. ... quotes and escaping quotes in parameters with backslashes is a method ...
    (comp.lang.tcl)
  • 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)