[GRASS-dev] question about python scripts on Windows again
Glynn Clements
glynn at gclements.plus.com
Wed Jan 27 10:24:15 EST 2010
Michael Barton wrote:
> >> Some time back, I asked how users could create a python script that runs
> >> under GRASS for windows. At the time, the answer was more or less: 'with
> >> great difficulty, if even possible'. There have been quite a few changes
> >> in the Windows builds over the past month or so and I am wondering if
> >> the answer is more optimistic now.
> >
> > The problem is that g.parser re-executes the script via $GRASS_SH,
> > which won't work for anything other than shell scripts. That hasn't
> > changed.
> >
>
> Thanks for the update.
There hasn't been an update; that's the problem ;)
> This is unfortunate and oddly ironic, since one of the rationales
> for the move to Python is that shell scripts must be run on Windows
> under a *nix emulator like msys, while Python can run native.
>
> Given what you say, why do Python scripts run on other platforms?
Because the use of $GRASS_SH is specific to Windows:
#ifdef __MINGW32__
{
/* execlp() and _spawnlp ( _P_OVERLAY,..) do not work, they return
* immediately and that breaks scripts running GRASS scripts
* because they dont wait until GRASS script finished */
/* execlp( "sh", "sh", filename, "@ARGS_PARSED@", NULL); */
/* _spawnlp ( _P_OVERLAY, "sh", "sh", filename, "@ARGS_PARSED@", NULL ); */
int ret;
char *shell = getenv("GRASS_SH");
if (shell == NULL)
shell = "sh";
ret =
_spawnlp(_P_WAIT, shell, shell, filename, "@ARGS_PARSED@", NULL);
G_debug(1, "ret = %d", ret);
if (ret == -1) {
perror("_spawnlp() failed");
return 1;
}
return ret;
}
#else
execl(filename, filename, "@ARGS_PARSED@", NULL);
perror("execl() failed");
return 1;
#endif
On Unix, we can just execl() the script, but that doesn't work on
Windows. The "quick fix" was to run the script via $GRASS_SH, which
was fine back when scripts were *always* shell scripts.
Alternatives include:
1. Parsing the #! line at the start of the script and selecting the
appropriate interpreter.
2. Adding a ".sh" extension to shell scripts, associating the ".sh"
extension with bash, and invoking the script via "cmd /c <command>".
3. Invoking the script via "$GRASS_SH -c '<command>'" and letting the
shell handle the #! line.
The main problem with both 2 and 3 is that we would need to construct
a suitable command line, quoting or escaping any characters which are
interpreted by the shell.
> > One solution is to merge the support for the -s switch from 7.0.
>
> What does the -s switch do?
It writes the option settings to stdout then quits, rather than trying
to re-invoke the script with the options added to the environment.
In 7.0, grass.script.parser() invokes g.parser with the -s switch and
parses its output to initialise the options/flags dictionaries.
--
Glynn Clements <glynn at gclements.plus.com>
More information about the grass-dev
mailing list