[GRASS-dev] Re: [GRASS GIS] #1447: wxGUI wingrass scripts need
whitespace in path
GRASS GIS
trac at osgeo.org
Fri Sep 23 15:39:48 EDT 2011
#1447: wxGUI wingrass scripts need whitespace in path
------------------------------+---------------------------------------------
Reporter: mmetz | Owner: grass-dev@…
Type: defect | Status: new
Priority: major | Milestone: 6.4.2
Component: wxGUI | Version: svn-releasebranch64
Keywords: wingrass, spaces | Platform: MSWindows XP
Cpu: All |
------------------------------+---------------------------------------------
Comment(by mmetz):
Replying to [comment:10 glynn]:
> Replying to [comment:8 mmetz]:
>
> > The *args argument to subprocess.Popen [0] is a list of arguments.
>
> Note: args is a list of Popen's non-keyword arguments. args[0] should be
a list containing the program's arguments. len(args) should always be 1;
all arguments except for the first one ("args") should be passed as
keyword arguments, not positional arguments.
>
> While subprocess.Popen()'s first argument can be a string, this feature
probably shouldn't be used. It's too easy to get it wrong.
The horrible hack worksforme. But I am aware that any string protection
which is normally done by Subprocess.Popen's string conversion, would then
need to be done by the wxGUI, and lib/python/task.py.
>
> > subprocess.Popen converts the arguments differently, depending on
whether there is whitespace in an argument or not.
>
> subprocess.Popen() has to convert the argument list to a command string
according to the rules by which MSVCRT parses the command string into
arguments, so that the program's main() ends up seeing the correct argv[].
One of those rules is that strings containing whitespace must be quoted.
That's all fine for programs that have a main(), but shell scripts don't
have main(). I think that is the reason why the current implementation
works for real programs but not for scripts. MSVCRT rules do not (need to)
cater for strings passed to cmd.exe, then to %GRASS_SH%. AFAICT, a file
path without whitespaces is passed ok to the Windows shell (cmd.exe), but
then further passed to %GRASS_SH%, yet another shell, and there the (by
now unprotected) backslashes get lost if not quoted properly.
>
> Because the underlying Windows interface (!CreateProcess) treats a
command line as a string, rather than as a list of strings (as is the case
for Unix' execve()), there isn't any 100% reliable way of ensuring that
the program gets the correct argv[] passed to its main() function
(historically, DOS programs were often written in assembler and didn't
have a main(), while Windows programs use !WinMain rather than main()).
The best that you can do is to assume that the program parses the command
line according to the MSVCRT rules (there's a URL in the subprocess.py
file). If it doesn't, you lose.
Same as above, 1) worksforme, 2) we could do that horrible hack for
scripts only.
>
> > The result is meant as input for programs and apparently sometimes
incompatible with "sh -c <grass.module> <arguments>". The problem for file
input arguments arises if there is no whitespace in there because sh
removes all backslashes left over by subprocess.Popen. The workaround is
to convert the *args list into one long string with whitespaces, file
paths quoted earlier when creating the command:
>
> Before attempting this, first please confirm that the data being passed
to `subprocess.Popen.__init__` by gcmd.Popen() is actually correct.
len(args) should be 1, args[0] should be a list of strings, none of those
strings should have any quoting or escaping (beware of Python's own
quoting/escaping if repr() is used). If this isn't the case, then the
problem lies elsewhere, and trying to correct for it in gcmd.Popen would
actually mean introducing an "equal but opposite" bug.
The strings indicating file paths do have escaping under Windows within
the wxGUI, but it's \ that is escaped to \\, looks fine to me. These
strings are converted somewhere inside subprocess.Popen to protect
whitespaces, but not to protect backslashes (escapes). I'm pretty sure
that this is the problem for scripts because what the sh shell sees is
e.g. \I and not \\I, i.e. the backslash gets lost (see above). I have
tested in wxGUI with v.in.geonames (script) and v.in.ogr (real program)
and there is no quoting before subprocess.Popen is called. Quoting appears
as output of subprocess.Popen if an argument contains whitespace.
The fix causes subprocess.Popen to protect everything because the program
and its args are passed as one single string which means that protection
of single arguments, e.g. input="D:\Grass_test_data\IT\It.txt" must be
done manually.
I am aware that this is not looking ideal. Any better ideas?
>
> Second, ensure that any "fix" for shell scripts DOESN'T go into 7.0. On
Windows, 7.0 needs to work with binaries, Python scripts and (cmd.exe)
batch files, and it needs to do so reliably. If that means that it doesn't
work with bash scripts, tough.
I am aware of that ;-)
Markus M
--
Ticket URL: <https://trac.osgeo.org/grass/ticket/1447#comment:11>
GRASS GIS <http://grass.osgeo.org>
More information about the grass-dev
mailing list