[GRASS-dev] gis.m in wingrass: using where clause in d.vect causes error :can't read "_data(.gronsole.gronsole, 9, donecmd)": no such element in array

Glynn Clements glynn at gclements.plus.com
Mon Oct 9 23:22:15 EDT 2006


Moritz Lennert wrote:

> >> Huidae or Glynn, any ideas on this ?
> > 
> > 	# Actually run the program
> > 	if { $mingw == "1" } {
> > 		# shell scripts require sh.exe.
> > 		set cmd [concat | sh -c '$cmd']
> > 	} else {
> > 		set cmd [concat | $cmd 2>@ stdout]
> > 	}
> > 
> > If you want to use "sh -c ...", you have to escape any shell
> > metacharacters, otherwise commands which happen to contain shell
> > metacharacters (e.g. "<" or ">" in a SQL "WHERE" clause) won't work.
> > 
> > I've already explained this in the thread discussing these changes.
> 
> Found
> http://grass.itc.it/pipermail/grass5/2006-September/025834.html
> 
> where you say
> 
>  "The simplest solution to the issue of
>  metacharacters is to replace any occurrences of the single quote
>  character in arguments with "'\''" (quote, backslash, quote, quote)
>  and surround each argument with single quotes.
>  
>  Even then, there might be issues due to the shell messing with the
>  environment, signal handling, process groups etc (as well as possible
>  Unix-compatibility "features"). Shells are very complex programs."
> 
> Not sure that I understand exactly what needs to be done and where.

In the above Tcl code, $cmd is a Tcl list (a string using a specific
syntax which ensures that element boundaries are preserved even when
elements contain spaces etc).

Using that string as an argument to "sh -c ..." will only work
correctly if the format of the string is such that the shell will
parse it into the same list of strings that Tcl would. In practice,
this will only happen if none of the elements contain any characters
which are significant to either Tcl or the shell (which includes
spaces, as they are normally treated as element separators).

IOW, "sh -c '$cmd'" will only work for commands where none of the
arguments contain either Tcl or shell metacharacters. If you want to
invoke $cmd via "sh -c ...", you have to take the list apart and
construct a command line using shell syntax.

E.g. (untested):

	set shcmd ""
	foreach arg $cmd {
		set arg2 [regsub -all {'} $arg {'\''}]
		if {$shcmd == ""} {
			set shcmd "'$arg2'"
		} else {
			set shcmd "$shcmd '$arg2'"
		}
	}
	set cmd [concat | sh -c $shcmd]

However, for various reasons, it would be better if we could find a
way avoid using "sh -c ..." altogether. The problem there is that you
can't directly execute shell scripts on Windows.

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-dev mailing list