From: ram on
Hi all,
I am posting this again as i really need help for this. Just
point me in the right direction and i'll run with it.
Is there a way to read the output of a particular command into
a variable. I am thinking something in the lines of

#! /bin/sh
# -*- tcl -*- \
exec tclsh "$0" ${1+"$@"}

# This is required to declare that we will use Expect
package require Expect

spawn telnet host_ip
send "password\r"

send "date\r"

Here the kernel will output the date on the screen. Is there
a way to read this output into a string variable.

Thanks,
ram
From: Cameron Laird on
In article <ba9ad0d3-b5c9-40be-8124-d9210028973b(a)y22g2000prd.googlegroups.com>,
ram <ramjothikumar(a)yahoo.com> wrote:
>Hi all,
> I am posting this again as i really need help for this. Just
>point me in the right direction and i'll run with it.
> Is there a way to read the output of a particular command into
>a variable. I am thinking something in the lines of
>
>#! /bin/sh
># -*- tcl -*- \
>exec tclsh "$0" ${1+"$@"}
>
># This is required to declare that we will use Expect
>package require Expect
>
>spawn telnet host_ip
>send "password\r"
>
>send "date\r"
>
> Here the kernel will output the date on the screen. Is there
>a way to read this output into a string variable.
.
.
.
I'm not sure at what level you want help. There
are multiple problems with what you write. <URL:
http://wiki.tcl.tk/2958 > has the answer, but I
suspect it might be opaque to you. You might
start by appending

expect *
puts expect $expect_out(buffer)

to your script, although it's going to take a lot
more than that to harden it.
From: Victor on
On Jun 25, 8:24 pm, cla...(a)lairds.us (Cameron Laird) wrote:
> In article <ba9ad0d3-b5c9-40be-8124-d92100289...(a)y22g2000prd.googlegroups..com>,
>
>
>
> ram  <ramjothiku...(a)yahoo.com> wrote:
> >Hi all,
> >        I am posting this again as i really need help for this. Just
> >point me in the right direction and i'll run with it.
> >        Is there a way to read the output of a particular command into
> >a variable. I am thinking something in the lines of
>
> >#! /bin/sh
> ># -*- tcl -*- \
> >exec tclsh "$0" ${1+"$@"}
>
> ># This is required to declare that we will use Expect
> >package require Expect
>
> >spawn telnet host_ip
> >send "password\r"
>
> >send "date\r"
>
> >          Here the kernel will output the date on the screen. Is there
> >a way to read this output into a string variable.
>
>                         .
>                         .
>                         .
> I'm not sure at what level you want help.  There
> are multiple problems with what you write.  <URL:http://wiki.tcl.tk/2958> has the answer, but I
> suspect it might be opaque to you.  You might
> start by appending
>
>     expect *
>     puts expect $expect_out(buffer)
>
> to your script, although it's going to take a lot
> more than that to harden it.- Hide quoted text -
>
> - Show quoted text -

At the beginning of this problem, what does this line try to do: exec
tclsh "$0" ${1+"$@"}

Thanks --
From: Cameron Laird on
In article <f3a969e1-efc8-4d47-bc1b-ec2154941486(a)x19g2000prg.googlegroups.com>,
Victor <vhnguyenn(a)yahoo.com> wrote:
>On Jun 25, 8:24�pm, cla...(a)lairds.us (Cameron Laird) wrote:
>> In article
><ba9ad0d3-b5c9-40be-8124-d92100289...(a)y22g2000prd.googlegroups.com>,
>>
>>
>>
>> ram �<ramjothiku...(a)yahoo.com> wrote:
>> >Hi all,
>> > � � � �I am posting this again as i really need help for this. Just
>> >point me in the right direction and i'll run with it.
>> > � � � �Is there a way to read the output of a particular command into
>> >a variable. I am thinking something in the lines of
>>
>> >#! /bin/sh
>> ># -*- tcl -*- \
>> >exec tclsh "$0" ${1+"$@"}
.
.
.
>At the beginning of this problem, what does this line try to do: exec
>tclsh "$0" ${1+"$@"}
>
>Thanks --

Does <URL: http://wiki.tcl.tk/812 > leave any questions?
From: Bezoar on
On Jun 25, 8:00 pm, ram <ramjothiku...(a)yahoo.com> wrote:
> Hi all,
> I am posting this again as i really need help for this. Just
> point me in the right direction and i'll run with it.
> Is there a way to read the output of a particular command into
> a variable. I am thinking something in the lines of
>
> #! /bin/sh
> # -*- tcl -*- \
> exec tclsh "$0" ${1+"$@"}
>
> # This is required to declare that we will use Expect
> package require Expect
>
> spawn telnet host_ip
> send "password\r"
>
> send "date\r"
>
> Here the kernel will output the date on the screen. Is there
> a way to read this output into a string variable.
>
> Thanks,
> ram

Heres a better example using ssh. I highly recommend ssh over telnet
since you
can remotely execute commands without having to worry about prompts
etc. In the above you really should wait for the prompt before
executing the command otherwise it will likely depend on the load of
the remote machine as to wether it will work or not. With ssh you can
do as follows($> is the prompt):

$>ssh chuck(a)tcl.tk ls -1

If you have certificates configured it will run without asking for a
password. which means you could ( in tcl ) use exec as not interaction
would be necessary. Otherwise it will look for a password.

$>chuck(a)tcl.tk password :
file1
file2
file3

Using expect we can input the password and also check for errors (like
a wrong password). Like Cameron indicated, this is the hardening part.
Luckily, I have an example you can build from. The following may or
may not work on your system as the implementation of ssh do not follow
a convention on what text should be used when issuing an error message
or the password prompt. You will need to change these regexps to match
your system if they do not work. Use the log_user and the exp_internal
to check your regexps.

HTH
Carl

run like <scriptfile> host user password command arg1 ... argN

e.g a error example host and user reversed :
expect comes back with exit code 255

$>execremote.tcl carl 198.3.2.24 xxxxx date
spawn ssh -p 22 -t 198.3.2.24(a)carl date
Command date completed with status : 2346 exp6 0 255 ok
Press ENTER to see results or q to quit:
carl: Name or service not known
===============
Press ENTER to see results or q to quit:

e.g a good example

$>execremote.tcl 198.3.2.24 carl xxxxxxx date
spawn ssh -p 22 -t carl(a)198.3.2.24 date
Command date completed with status : 2354 exp6 0 0 ok
Press ENTER to see results or q to quit:
Thu Jun 26 17:19:22 CDT 2008
===============
Press ENTER to see results or q to quit:

------------------SCRIPT START --------------------

#!/bin/sh
# the next line restarts using wish \
exec tclsh "$0" ${1+"$@"}

if { [ catch {package require Expect } err ] != 0 } {
puts stderr "Unable to find package expect ... adjust your
auto_path!";
}
proc remoteExec { buff host user password command {timeout 30 } { port
22 } } {
upvar $buff buffer
set pid [ eval spawn ssh -p $port -t $user@$host $command ]
set my_id $spawn_id;
set bad 0;
set done 0;
set timeout $timeout
exp_internal 0; # set to one for extensive debug
log_user 0; # set to one to watch action
set status "ok"
set sentPassword 0
expect {
-i $my_id
-re {assword} {
exp_send "$password\r"
set sentPassword 1
exp_continue;
}
-re {Permission denied, please try again\.} {
set status "Unable to login"
exec kill -9 $pid
set buffer ""
}
-re {: } {
;# note this is the : from the password prompt
# it needs to be last and any login error need to go
# above. If it is seen before any error we can assume
# that we have logged in . Its a hack to separate the
# login from the output of the command
}
timeout {
set status "timeout"
# kill process and go around once more to clean up
# in eof
exec kill -9 $pid

}
eof {
append buffer "$expect_out(buffer)\n";
set done 1
set status "premature eof on login"
}
}
if { !$done } {
expect {
-i $my_id
-re "(.*)Connection to $host closed\\." {
append buffer "$expect_out(1,string)\n";
exp_continue;
}
-re {.+} {
append buffer "$expect_out(buffer)";
exp_continue;
}
timeout {
set status "timeout"
# kill process and go around once more to clean up
# in eof
exec kill -9 $pid
exp_continue;
}
fullbuffer {
append buffer "$expect_out(buffer)";
exp_continue;
}
eof {
append buffer "$expect_out(buffer)";
}
}
}
# note proper way to close out an expect
set exitstatus [ exp_wait -i $my_id ];
catch { exp_close -i $my_id };
# let caller know that if status was kill it was
# because of timeout
lappend exitstatus $status
return $exitstatus
}
set host [lindex $argv 0 ]
set user [lindex $argv 1 ]
set passwd [lindex $argv 2 ]
set command [ lrange $argv 3 end ]
set buff ""
set result [ remoteExec buff $host $user $passwd $command 10 22 ]
set buff [string map { "\r" "" } [string trim $buff]]
puts " Command $command completed with status : $result"
while { 1 } {
puts -nonewline "Press ENTER to see results or q to quit:"
flush stdout
set old [ fconfigure stdin ]
fconfigure stdin -blocking 1 -buffering none
gets stdin line
eval fconfigure stdin $old
if { [regexp -- {q|Q} $line ] } {
break;
}
puts stdout "$buff"
puts stdout "==============="
}
exit 0