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

wrong # args: should be "proc name args body"

3,914 views
Skip to first unread message

amarnat...@gmail.com

unread,
Dec 5, 2006, 2:15:58 AM12/5/06
to
Hi Folks,

I'm very new to tcl programming and hit with a problem. Hoping for
some guidence.

The program is to use ssh / telnet to connect to a host based on
command line args. When this is run as a script it gives below error,
but same work fine when invoked through tclsh shell.

Kindly help me.

"wrong # args: should be "proc name args body"
while executing
"proc ssh_login {userid _host _pass} {
spawn ssh -l $userid $_host
expect {
timeout {
"


++++++++++ ACTUAL SCRIPT+++++++++
#!/usr/bin/expect -d


proc ssh_login {userid _host _pass} {
spawn ssh -l $userid $_host
expect {
timeout {
puts "ssh session timed out"
exit 1
}
-re "Are you sure you want to continue connecting" {
send -- "yes \r"
exp_continue
}
-re "(?i)password: " {
}
}
sleep 1
send -- "$_pass\r"
} # end of proc ssh_login

proc telnet_login { userid _host _pass } {
spawn telnet
expect {
timeout {
puts "telnet timed out"
exit 2
}
-re "(?i)login" {
send -- "$userid\r"
exp_continue
}
-re "(?i)password" {
sleep 1
send -- "$_pass\r"
}
}
} #end of telnet_login

global _host
global userid
global _pass
global RDA_PATH
global sess

set timeout 19

if { [llength $argv ] < 4 } {
puts " pass the command argument"
exit 1
} else {
set _host [lindex $argv 0]
set userid [lindex $argv 1]
set _pass [ lindex $argv 2]
set RDA_PATH [lindex $argv 3]
set sess [lindex $argv 4]
puts " Connecting to Host $_host with $sess "
}

if { $sess = "ssh" } {
ssh_login $userid $_host $_pass
} else {
telnet_login $userid $_host $_pass
}

if { $sess_r != 0 } {
puts "failed to establish a session with $_host"
exit 3
}

expect -regexp "(\$|\#|\>)" {
sleep 2
exp_send {PS1='RDA>'}
send -- "\r"
send -- "cd $RDA_PATH \r"
}
interact
==========================

Stéphane A.

unread,
Dec 5, 2006, 2:42:14 AM12/5/06
to

amarnat...@gmail.com a écrit :

> Hi Folks,
>
> I'm very new to tcl programming and hit with a problem. Hoping for
> some guidence.
>
> The program is to use ssh / telnet to connect to a host based on
> command line args. When this is run as a script it gives below error,
> but same work fine when invoked through tclsh shell.
>
> Kindly help me.
>
> "wrong # args: should be "proc name args body"
> while executing
> "proc ssh_login {userid _host _pass} {
> spawn ssh -l $userid $_host
> expect {
> timeout {
> "

You have at the last lign:


> } # end of proc ssh_login

A comment must start, either at the beginning of a line,
either after the end of a command after a semicolon.

So you need :

}; # end of proc ssh_login

Regards,
Stephane

amarnat...@gmail.com

unread,
Dec 5, 2006, 3:12:19 AM12/5/06
to
Hi Stephane,

Your explanation did the miracle.
Thanks a lot for your help.

Regards,
Amar

Cameron Laird

unread,
Dec 5, 2006, 9:34:57 AM12/5/06
to
In article <1165306339.2...@80g2000cwy.googlegroups.com>,

<amarnat...@gmail.com> wrote:
>Hi Stephane,
>
> Your explanation did the miracle.
>Thanks a lot for your help.
.
.
.
I gratuitously offer my own reaction: among the best ways
to give thanks for help with Tcl is to recognize that it
involves no miracles (or at least none at this level). As
your experience with the language grows, you'll find that
it favors simplicity rather than mystery. In the case at
hand, the syntax rules are few and straightforward, and,
with practice, you'll learn to recognize corrections and
solutions on your own.

Glenn Jackman

unread,
Dec 5, 2006, 11:26:21 AM12/5/06
to
Some notes intermingled...

At 2006-12-05 02:15AM, "amarnat...@gmail.com" wrote:
[...]


> proc ssh_login {userid _host _pass} {

Because you're performing your [spawn] in a proc, you have to say:

global spawn_id

first. This variable is implicitly used by [send] and [expect] commands
to point to the spawned process. Without declaring it global, the
spawn_id variable will only have local scope to this proc, and will
disappear when the proc returns.

You might also want to say:

global timeout

but it's not strictly required, as expect will look beyond the local
scope when reading a variable.

> spawn ssh -l $userid $_host
> expect {
> timeout {

[...]


> } # end of proc ssh_login
>
> proc telnet_login { userid _host _pass } {

As above:
global spawn_id

> spawn telnet
[...]


> } #end of telnet_login
>
> global _host
> global userid
> global _pass
> global RDA_PATH
> global sess

When you're in the global space (outside of a proc), it is unnecessary
to explicitly declare variables as global.

> set timeout 19
>
> if { [llength $argv ] < 4 } {
> puts " pass the command argument"
> exit 1
> } else {
> set _host [lindex $argv 0]
> set userid [lindex $argv 1]
> set _pass [ lindex $argv 2]
> set RDA_PATH [lindex $argv 3]
> set sess [lindex $argv 4]

The following Tcl idiom is more concise:

foreach {_host userid _pass RDA_PATH sess} $argv {break}

You might want to use a more consistent variable naming convention.

> puts " Connecting to Host $_host with $sess "
> }
>
> if { $sess = "ssh" } {
> ssh_login $userid $_host $_pass
> } else {
> telnet_login $userid $_host $_pass
> }
>
> if { $sess_r != 0 } {

The sess_r variable is as yet undefined, so you'll get an error there.

> puts "failed to establish a session with $_host"
> exit 3
> }
>
> expect -regexp "(\$|\#|\>)" {
> sleep 2
> exp_send {PS1='RDA>'}
> send -- "\r"

Again, consistency: use [exp_send] or [send] but not both.

> send -- "cd $RDA_PATH \r"
> }
> interact
> ==========================
>


--
Glenn Jackman
Ulterior Designer

0 new messages