TCL problem. Can someone help?

David Rysdam david at rysdam.org
Fri Nov 5 07:16:20 EDT 2010


An agent or agents purporting to be Bruce Dawson said:
> 
> On 11/04/2010 11:09 PM, Steven W. Orr wrote:
> > On 11/4/2010 11:41 AM, David Rysdam wrote:
> >> An agent or agents purporting to be Steven W. Orr said:
> >>> I have a stupid question in tcl that I'm just not getting. I'm hoping to get
> >>> lucky here.
> >>>
> >>> I have a script in tcl/expect that spawns su and needs to pass its arguments
> >>> to su.
> >>>
> >>> argv in tcl has the command line args. I lop off the first couple of args that
> >>> I need in my script via:
> >>>
> >>> set user [lindex $argv 0]
> >>> set passwd [lindex $argv 1]
> >>>
> >>> Then I want to pass the *rest* of the args to su. What I have is this:
> >>>
> >>> spawn su - $user -c "[lrange $argv 2 end]"
> >>>
> >>> If I call me script
> >>>
> >>> sss me secret 'pwd; ls'
> >>>
> >>> Then what happens is this:
> >>>
> >>> spawn su - swagent -c {pwd; ls;}
> >>> Password:
> >>> -bash: -c: line 0: syntax error near unexpected token `}'
> >>> -bash: -c: line 0: `{pwd; ls;}'
> >>>
> >>> I vershtumped about where the braces are coming from. found out that if I pass
> >>> a single command without any semicolon , it works ok.
> >> The braces are there because the result of the lrange is a list.  The
> >> way we handle this in our code (which may not be The Right Way) is by
> >> doing something this:
> >>
> >> set args [lrange $argv 2 end]
> >> eval {spawn su - $user -c} "$args"
> >>
> >> (I don't know if you need the quotes for either spawn or su, so those
> >> might be extraneous or need some special quoting or something.)
> >>
> >> Newer versions for Tcl (and therefore Expect?) also have an expand
> >> operator that probably does this better, but I don't know if you are
> >> using that.
> > I'm impressed. Thanks
> 
> Note that the 'join' operator removes the top level of braces. This may
> not be the right thing to do in all circumstances, but it frequently
> helps when you need to get rid of extraneous braces.

join turns a list into a string and you are right that that might be
the right thing to do for either su or spawn, depending on what it is
expecting (see what I did there?!).  Sometimes a command (internal or
external) wants a single string with embedded spaces (i.e. from join)
and sometimes it wants multiple items (i.e. the result of expanding
the list).

It's a subtle Tcl thing that's bitten me a million times, which is why
I recognized it immediately.


More information about the gnhlug-discuss mailing list