Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Trying to connect to 3 machine names 1

Status
Not open for further replies.

pcdj

Programmer
Oct 17, 2002
11
US
Need to start three machines at the same time
 
And, you think tcl/expect can help you with this?
Don't know bout that.
 
I was trying to use expect and spawn the ssh machines. I am very new.
 
Okay, that makes sense.
Sorry for the sarcasm.

Yes it can be done, and easily.
Please let me know what you need to do..
If it's very simple like just starting three instances of
ssh and then being able to switch back and forth between
them, that is very easy to accomplish.


Regards..
 
I need to connect to 3 machines using ssh then prompt for password then go to cd /file then start program then have the 3 machines logs come up. Can you help with this.
 
Sure.
I don't use ssh because of it's security history
anymore however, so I don't have it installed. I can do
the same with an example for any login program however.
Let me come up with an example, test it, and I'll post
some code asap.
 
Alright, You said you were new to expect so please don't be frightened off by this. Others have different ways of doing things. If you need help with the program, please feel free to ask.
You will need to give me regexp matches in the login
sequence for ssh most probably.

\\<start\\>
#!/usr/bin/expect
####BUILTIN DEBUGGING##############
#uncomment the line below for detailed debugging feedback
#exp_internal 1
####################################

########settings for program#####
array set allInfo {
spawnids &quot;&quot;
logfile &quot;tmp.txt&quot;
ider &quot;uname -a ; whoami&quot;
direc &quot;/home&quot;
debug 0
prompt &quot;.*@.*&quot;
timeout &quot;1000&quot;
}

####set allInfo(debug) to 1 for a constant trace against interact.#########
if {$allInfo(debug) > 0} {
trace variable interact_out w [list AlertMe]
}
set timeout $allInfo(timeout)
################procedures####################
#logging procedure, writes to file specified in allInfo(logfile)
proc Elogger {linfo} {
global allInfo
if {![catch {set fd [open $allInfo(logfile) &quot;a+&quot;]}]} {
puts $fd &quot;$linfo\n&quot;
catch {flush $fd}
close $fd
}
return
}

#reads all id's in allInfo(spawnids) and compares them prompting you to change
#if you'd like to another login host
proc switch_host {id} {
global allInfo
foreach cid $allInfo(spawnids) {
send_user &quot;Current id = $id\n&quot;
send_user &quot;Switch to $cid (?) \[y/n\] :&quot;
set ans [gets stdin]
if {&quot;$ans&quot; == &quot;y&quot; || &quot;$ans&quot; == &quot;Y&quot;} {
concentrator $cid
}
}
return
}

#main procedure ::takes care of the interacting..
#think of it as a traffic cop ;)
proc concentrator {id {cmd &quot;&quot;}} {
global user_spawn_id allInfo interact_out
set spawn_id $id

if {[info exists cmd] && [string length $cmd] > 1} {
send &quot;$cmd\r&quot;
expect -re &quot;$allInfo(prompt)&quot; {
send_user &quot;$expect_out(buffer)\n&quot;
}
}

usage
send &quot;$allInfo(ider)\r&quot;
interact {
&quot;~SWTH&quot; {switch_host $spawn_id ; Elogger &quot;Changed to $spawn_id&quot;}
&quot;~CDIR&quot; {send_all_ids &quot;cd $allInfo(direc)\r&quot;}
&quot;~LOGV&quot; {send_all_ids &quot;tail -n100 /var/log/messages\r&quot;}
&quot;~CMD&quot; {send_user &quot;Command to send to all hosts: &quot; ; set mcmd [gets stdin] ; send_all_ids &quot;$mcmd\r&quot;}
&quot;~QUIT&quot; {send_all_ids &quot;exit\r&quot; ; catch {send_user &quot;[parray interact_out]\n&quot;} ; Elogger &quot;Disconnect at [clock format [clock seconds]]&quot; ; exit}
&quot;~USE&quot; {usage}
}

-o
timeout 200 {
send_all_ids &quot;\r\n&quot;
send_user &quot;Sent keepalive to all hosts&quot;
}
}

#if allInfo(debug) is set > 0 this trace will become active against all writes to interact_out.
proc AlertMe {x y z} {
global interact_out
catch {send_user &quot;Caught new write event to array interact_out: [parray interact_out]\n&quot;}
return
}

#a usage blurb, lets you know whats going on and how to do it.
proc usage {} {
global user_spawn_id
send -i $user_spawn_id &quot;Usage for [info script]. Once connected you may issue any of the following commands:\n ~SWTH: Switches you to an individual host \n ~CDIR: sends all hosts the command cd to the configured directory in the array allInfo \n ~LOGV: sends all hosts the command as tail -n100 /var/log/messages \n ~CMD: prompts user for command to send to all connected hosts \n ~QUIT: sends all hosts exit and then does some final checks. \n ~USE: reprints this usage message \n \r\n\n&quot;
}

#sends $cmd to all id's in $allInfo(spawnids)
proc send_all_ids {cmd} {
global allInfo

foreach id $allInfo(spawnids) {
send -i $id &quot;$cmd\r&quot;
expect -i $id -re $allInfo(prompt) {
send_user &quot;Read $expect_out(buffer)\n&quot;
catch {Elogger $expect_out(buffer)}
}
}
return
}


########end procedures#################################


#################MAIN()#################################
##for the main portion we read from the number of args to #the script(each a hostname) and connect to these recording #their id's in our idlist
#we should probably handle the login initially one at a #time so that we can handle errors then we'll interact with #the first id##########
if {[llength $argv]} {
for {set i -1} {$i <= [llength $argv]} {incr i} {
if {[string length [lindex $argv $i]]} {
spawn ssh myname@[lindex $argv $i] ;# you need to #replace this with a valid ssh loginstring
lappend allInfo(spawnids) $spawn_id
send_user &quot;Connecting to: [lindex $argv $i]\n&quot;
expect {
-re &quot;Pass.*&quot; { ;# you need to replace this #prompt with the password prompt sent by your ssh #machines.####################
send_user &quot;Password for [lindex $argv $i]&quot;
set pass [gets stdin]
send &quot;$pass\r&quot;
expect -re &quot;$allInfo(prompt)&quot; {
send &quot;\rTERM=vt100\r&quot;
}
}
}
}
}
} else {
error &quot;You must specify at least one host to connect to&quot;
} ;#all done

####now connect to the first of the hosts,and start #stuff####################
puts &quot;$allInfo(spawnids) , idlist&quot;
concentrator [lindex $allInfo(spawnids) 0] $allInfo(ider)
\\<end\\>

This has been tested with a login program and works well.
Not the prettiest thing, but usable.

 
Thanks for the help. I will try using. If I have question I will ask. Thanks again
 
It works. I need to know how I would list Machines 1, Machine 2, and Machine 3 to log in to at the same time. Thanks again.
 
>Scriptname host1 host2 host3 host4 host5 host6, etc..

I didn't have many problems with it, but it's not big
on error catching during the logon process. It does
log some stuff.

Glad it works for you.

Seeya,
M
 
Would I put Scriptname host1 host2 host3 using your code.
 
When you call the program:
>expectscript host1..
It can take 'n' more hosts in the argv list.
So calling it like:
>expectscript host1 host2
Will spawn and run you through the process of logging
into these hosts one at a time. It will record the spawn_ids in the array element allInfo(spawnids).

It will then attach you to the first host that you
specified on the cli after the scriptname.

Simultaneously, all the other login instances are
maintained by interact. There are various macros
described in the concentrator procedure that will allow
you to send commands to all spawn_ids simulataneously.
The output of these commands is sent to the user.

You can switch to an individual host by issuing
the ~SWTH macro command, you will be prompted for
which id you want, with your current id identified.
Once you choose one with &quot;y&quot;,you interact with
the selected host and uname -a and whoami is sent to
the host so you can tell where you are at.

If you have an episode of entering a command and it
doesn't seem to do anything just \r again. Sometimes
expect snarfs keystrokes looking for patterns, or a procedure may be missing a necessary \r.

Feel free to improve the script or let me know when
you are having a particular problem.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top