Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

expect - spawn fails with argument list

232 views
Skip to first unread message

John L

unread,
Aug 8, 2007, 10:03:23 AM8/8/07
to
I have an expect script (call it blah.tcl) like this:

>>>
#!/usr/local/bin/expect -f

spawn $argv

expect "foo"
send "bar\r"
...
<<<

The goal is to be able to pass in to blah.tcl, the name of a
program/script to spawn along with all its arguments. Like this:

>>>
$ blah.tcl ftp xxx.xxx.xxx.xxx
<<<

But, when I try this, I get the following error:

>>>
couldn't execute "ftp xxx.xxx.xxx.xxx": no such file or directory
while executing
<<<

I looks like spawn is treating the whole string "ftp xxx.xxx.xxx.xxx" as
a single program name rather than a program name with an argument. I
can make this work by separating the arguments in the spawn call:

>>>
spawn [lrange $argv 0 0] [lrange $argv 1 1]
<<<

But, this only works for a program name with one argument. How do I
make this work with an arbitrary number of arguments?

I am using expect version 5.32.1.

Thanks!
John

Glenn Jackman

unread,
Aug 9, 2007, 9:24:46 AM8/9/07
to
At 2007-08-08 10:03AM, "John L" wrote:
> I have an expect script (call it blah.tcl) like this:
>
> >>>
> #!/usr/local/bin/expect -f
>
> spawn $argv
[...]
> $ blah.tcl ftp xxx.xxx.xxx.xxx
[...]

> couldn't execute "ftp xxx.xxx.xxx.xxx": no such file or directory
[...]

> I looks like spawn is treating the whole string "ftp xxx.xxx.xxx.xxx" as
> a single program name rather than a program name with an argument. I
> can make this work by separating the arguments in the spawn call:

eval spawn $argv



> spawn [lrange $argv 0 0] [lrange $argv 1 1]

FYI, [lindex $argv 0] is probably slightly more efficient than
[lrange $argv 0 0]

Further off topic, a common Tcl idiom (until 8.5) to assign the values
of a list to a set of variables is:
foreach {firstvar secondvar thirdvar} $list break


--
Glenn Jackman
"You can only be young once. But you can always be immature." -- Dave Barry

Bryan Oakley

unread,
Aug 9, 2007, 10:14:32 AM8/9/07
to
Glenn Jackman wrote:
> At 2007-08-08 10:03AM, "John L" wrote:
>> I have an expect script (call it blah.tcl) like this:
>>
>> >>>
>> #!/usr/local/bin/expect -f
>>
>> spawn $argv
> [...]
>> $ blah.tcl ftp xxx.xxx.xxx.xxx
> [...]
>> couldn't execute "ftp xxx.xxx.xxx.xxx": no such file or directory
> [...]
>> I looks like spawn is treating the whole string "ftp xxx.xxx.xxx.xxx" as
>> a single program name rather than a program name with an argument. I
>> can make this work by separating the arguments in the spawn call:
>
> eval spawn $argv
>
>> spawn [lrange $argv 0 0] [lrange $argv 1 1]
>
> FYI, [lindex $argv 0] is probably slightly more efficient than
> [lrange $argv 0 0]

Not to mention the fact that lrange returns a list and lindex returns a
single value, and a list of one element won't necessarily have the same
string representation as just the element itself.

It's probably a moot point for the types of data likely to be used by
the original poster, but code using lrange in this manner certainly can
fail for certain types of data.


--
Bryan Oakley
http://www.tclscripting.com

John L

unread,
Aug 9, 2007, 5:22:06 PM8/9/07
to
Yup, the answer was:

>>>
eval spawn $argv
<<<

And thanks for the lindex tip, too. Thanks for the help!

John

Uwe Klein

unread,
Aug 10, 2007, 7:01:38 AM8/10/07
to
John L wrote:
> Yup, the answer was:
>
> >>>
> eval spawn $argv
> <<<

if 1 [linsert $argv 0 spawn ]

uwe

Uwe Klein

unread,
Aug 10, 2007, 1:12:38 PM8/10/07
to
Ha,
and with tcl 8.5 it is even easier:

spawn {*}$argv

see http://wiki.tcl.tk/17158
>
uwe
>

0 new messages