Example expect script I dont fully understand posted by Brian due to missing code. This does exactly what im trying to accomplish if it works and anyone knows how to fill in the missing pieces.
A basic overview of what this script is doing is in order. First it spawns an ssh session to host/hosts, su - to root, runs a simple command to stop/kill a process then restart it. The command run to restart the process works from the command line on the servers themselves. Copy of restart command that is called by the expect script.
When i run the expect script it logs into the machine/machines in question and will su with success. The restart command has to be run as the specific user, so in order to call the restart script, i call a simple script that executes su - prfmgr -c "/opt/prfmgr/scripts/apmrestart.sh" this also works from the command line, but when the expect script calls this script it shuts down the processes, kills them if they hang, restarts everything sucessfully, (in the script is a ps -ef |egrep "all|the|process|names" that returns and shows sucessful restart. But it seems that when the script exits, it kills the processes it just started up. Is there anyway to keep this from happening? I've attatched the important parts of the script (sans passwords of course). If anyone can see why this would happen please let me know.
proc restart_apm {} {
global ssh_id DEBUG
# Return code constants set SUCCESS 0 set EFAIL 1 set ETIME 255 ;# Interaction timedout
set timeout 30 set return_value -1
# Login responses set root_prompt "# " set password_prompt "Password:" set sorry "Sorry, try again." set no_access "is not in the sudoers file.*" set syntax_err "sudoers file: syntax error*"
# Commands set restart "/root/apmstart.sh" set ps "/root/prfmgr-ps.sh"
} ;# end expect expect -i $ssh_id -re "$root_prompt" return $return_value } ;# end restart_apm
######## # # # MAIN # # # ########
foreach host $hosts { set timeout 30 if { $DEBUG == 1} { exp_internal 1 } # make sure host is pingable if { $DEBUG == 0} { log_user 0 }
# Start SSH process spawn /opt/local/bin/ssh -l biscadm $host; set ssh_id $spawn_id if { $DEBUG == 1} { exp_internal 1 } if { $DEBUG == 0} { log_user 0 }
# Execute login procedure set return_code [ssh_login 0] switch -- $return_code \ 0 { # If this is the final host status, we failed further down # but did not catch it. set status($host) "ssh: Successfully logged in" } 1 { set status($host) \ "FAILED: ssh: Known password(s) did not work" close -i $ssh_id; wait -i $ssh_id continue } 2 { set status($host) \ "FAILED: ssh: Authentication failed: account does not exist" close -i $ssh_id; wait -i $ssh_id continue } 3 { set status($host) \ "FAILED: ssh: Connection Refused: SSH not running or not allowed" close -i $ssh_id; wait -i $ssh_id continue } 4 { set status($host) \ "FAILED: ssh: SecurID prompt: requires interactive login" close -i $ssh_id; wait -i $ssh_id continue } 255 { # This is here just in case. This status should not show # up. We should be collecting something more specfic # than a timeout. set status($host) "FAILED: ssh: timeout (unexpected response)" close -i $ssh_id; wait -i $ssh_id continue } default { # This is BAD. The script should NEVER end up here. set status($host) "ERROR: ssh: check script (unknown return code)" close -i $ssh_id; wait -i $ssh_id continue }
if { $DEBUG == 0} { log_user 1 }
# Should be at a prompt at this point so send su set return_code [su_to_root 0] switch -- $return_code \ 0 { # If this is the final host status, we failed further down # but did not catch it. set status($host) "su: OK" } 1 { set status($host) \ "FAILED: su: Known password(s) did not work" close -i $ssh_id; wait -i $ssh_id continue } 2 { set status($host) "FAILED: su: No root account or bad passwd file" close -i $ssh_id; wait -i $ssh_id continue } 255 { # This is here just in case. This status should not show # up. We should be collecting something more specfic # than a timeout. set status($host) "FAILED: su: timeout (unexpected response)" close -i $ssh_id; wait -i $ssh_id continue } default { # This is BAD. The script should NEVER end up here. set status($host) "ERROR: su: check script (unknown return code)" close -i $ssh_id; wait -i $ssh_id continue }
# Should be at a root prompt at this point so send restart # Restart apm processes set return_code [restart_apm] switch -- $return_code \ 0 { set status($host) "SUCCESS" } 1 { set status($host) "FAILED: restart_prfmgr: prfmgr failed to restart" close -i $ssh_id; wait -i $ssh_id continue } 2 { set status($host) "FAILED: restart_prfmgr: /opt/prfmgr/scripts/apmrestart.sh: command not found" close -i $ssh_id; wait -i $ssh_id continue } 255 { # This is here just in case. This status should not show # up. We should be collecting something more specfic # than a timeout. set status($host) "FAILED: restart_prfmgr: timeout (unexpected response)" close -i $ssh_id; wait -i $ssh_id continue } default { # This is BAD. The script should NEVER end up here. set status($host) "ERROR: restart_prfmgr: check script (unknown return code)" close -i $ssh_id; wait -i $ssh_id continue }
puts "\n\n\nHost: Status:" puts "-------------------------------------------------------------" #Print the status of all hosts foreach host [array names status] { if { $host != "" } { set line [format "%-30s%-s" $host $status($host)] puts "$line\n" } }