lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

> -----Original Message-----
> From: [] On
> Behalf Of Peter Cawley
> Sent: zondag 17 november 2013 23:30
> To: Lua mailing list
> Subject: Re: Issue using quoted arguments on os.execute() on Windows
> I suspect that `os.execute(cmd)`, via the C runtime, ends up executing
> `"cmd.exe /C " .. cmd`.
> If you run `cmd.exe /?`, then part of the help text is the following:
> --8x--------------------------------------------------
> 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
>           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.
> --8x--------------------------------------------------
> The end effect of these rules is that if you want the sensible
> behaviour of quotes being preserved, and you want this consistently,
> then your command line mustn't start with a quote character. To that
> end, my personal approach is to do `os.execute("type NUL && "..cmd)`
> rather than `os.execute(cmd)`.

Thanks! Lifesaver, I spent almost a day on tracking this down.

I had just devised the following workaround; replace the full path by its short version;

function get_shortname(file)
   local cmd = [[for %f in ("]]..file..[[") do @echo %~df%~spf%~snf%~sxf]]
   local pipe = io.popen(cmd)  
   local short = pipe:read("*a")
   return short

So I wouldn't have to quote the command itself. But yours is better and universally applicable (I can monkeypatch os.execute() with that, and rest assured it works everywhere).