LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-12-2018, 04:15 PM   #1
cj_cheema
Member
 
Registered: Mar 2006
Location: INDIA
Distribution: RedHat, SuSE, Debian
Posts: 166

Rep: Reputation: 15
Exclamation Expect script stop running after getting an unresponsive host


Hi

I am using expect script for automatically executing the couple of commands and perform configuration in 500 Linux servers.

This expect script is working fine and able to run and perform configuration on reachable servers but issue is in provided list of servers if any host which is not reachable expect script get exit and couldn't move to next reachable server.
Below is the error which I am getting:

Quote:
ssh: Could not resolve hostname aplx445: Temporary failure in name resolution
send: spawn id exp5 not open
while executing
"send "$password\r""
("foreach" body line 11)
invoked from within
"foreach host $hosts {
# [spawn ssh -o StrictHostKeychecking=no $user@$host]
spawn ssh -o StrictHostKeychecking=no $user@$host
expect "pass..."
(file "./expect_main.exp" line 23)


Please have a look below my expect script and suggest how can my expect script skip the unresponsive server and move next to reachable servers.

Quote:
#!/usr/bin/expect -f
# This Script is created by Charanjit Singh it is created for the perpose of automating the Unix SA BAU tasks.

# Setting timeout limit after wait after running each command
set timeout 3


# Defining Login user and password
set user [lindex $argv 0]
set password [lindex $argv 1]

# Get the list of hosts, one per line #####
set fh [open "hosts.txt"]
set hosts [split [read $fh] "\n"]
close $fh

# Get the commands to run, one per line
set fc [open "commands.txt"]
set commands [split [read $fc] "\n"]
close $fc

# Iterate over the hosts
foreach host $hosts {
spawn ssh -o StrictHostKeychecking=no $user@$host
expect "password:"
send "$password\r"

# Become sudo
send "sudo su -\r"
expect "password:"
send "$password\r"

# Iterate over the commands
foreach cmd $commands {
expect "% "
send "$cmd\r"
}

# Tidy up
expect "% "
send "exit\r"
expect eof
}

Last edited by cj_cheema; 03-12-2018 at 04:20 PM. Reason: Adding error message
 
Old 03-12-2018, 04:27 PM   #2
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,230

Rep: Reputation: 712Reputation: 712Reputation: 712Reputation: 712Reputation: 712Reputation: 712Reputation: 712
Instead of using expect "password:" under spawn... line, try
Code:
expect {
    "error output you get when ssh not available" {
      exp_continue
    }
    "expect "password:"
}
edit: not tested, maybe replace "exp_continue" with "continue" if catching error prompt does not make it going to next loop iteration

Last edited by keefaz; 03-12-2018 at 04:33 PM.
 
Old 03-15-2018, 11:29 AM   #3
cj_cheema
Member
 
Registered: Mar 2006
Location: INDIA
Distribution: RedHat, SuSE, Debian
Posts: 166

Original Poster
Rep: Reputation: 15
Hi Keefaz

Thanks for your prompt response on my issue. I have tried to follow the same steps as you suggested but getting same error. It is still stucking on unresponsive hosts and take break from foreach loop.

Please find my modified expect script as per your suggestion as below:

Quote:
#!/usr/bin/expect -f
# Setting timeout limit after wait after running each command
set timeout 4


# Defining Login user and password
set user [lindex $argv 0]
set password [lindex $argv 1]

# Get the list of hosts, one per line #####
set fh [open "hosts.txt"]
set hosts [split [read $fh] "\n"]
close $fh

# Get the commands to run, one per line
set fc [open "commands.txt"]
set commands [split [read $fc] "\n"]
close $fc

# Iterate over the hosts
foreach host $hosts {
# [spawn ssh -o StrictHostKeychecking=no $user@$host]
spawn ssh -o StrictHostKeychecking=no $user@$host
expect {
"ssh: Could not resolve hostname aplx445: Temporary failure in name resolution" {
exp_continue
}
expect "password:"
}

# expect "password:"
send "$password\r"

# Become sudo
expect "$"
send "sudo su -\r"
expect "password:"
send "$password\r"

# Iterate over the commands
foreach cmd $commands {
expect "#"
send "$cmd\r"
}

# Tidy up
expect "# "
send "exit\r"
expect "$"
send "exit\r"
expect eof
}

}


I want this script should ignore at least below ssh errors:

1. Error:
ssh: Could not resolve hostname aplx445: Temporary failure in name resolution

2. And Second below Error:
ssh: connect to host 192.168.0.200 port 22: Connection timed out

Regards
Charanjit Singh
 
Old 03-15-2018, 11:53 AM   #4
Turbocapitalist
Senior Member
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 3,351
Blog Entries: 3

Rep: Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478
There are several mistakes in the above script.

One is that StrictHosKeyChecking ought to be set to "accept-new" ideally. It can be set to "yes" intead if the client does not handle "accept-new" there. Otherwise with it set to "no" and using passwords, then you guarantee that a man-in-the-middle (MitM) attack will have 100% success if someone tries it on your computers.

That leads to the second problem with the script: You need to be using keys for authentication instead of passwords. Use ed25519 if possible and RSA if backwards compatibility is needed.

Code:
ssh -i key.ed25519 -l $user $host "$cmd1; $cmd2; $cmd3; ..."
(For my edification, please say how you ended up trying expect instead of using keys. I'm getting the impression that some source is misleading people and I would like to track it down.)
 
1 members found this post helpful.
Old 03-15-2018, 12:58 PM   #5
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,230

Rep: Reputation: 712Reputation: 712Reputation: 712Reputation: 712Reputation: 712Reputation: 712Reputation: 712
@cj_cheema, pease read Turbocapitalist post, it's informative and more pratical

Quote:
Originally Posted by cj_cheema View Post
I want this script should ignore at least below ssh errors:

1. Error:
ssh: Could not resolve hostname aplx445: Temporary failure in name resolution

2. And Second below Error:
ssh: connect to host 192.168.0.200 port 22: Connection timed out

Regards
Charanjit Singh
I would try
Code:
...
spawn ssh -o ...
expect {
  timeout { continue; }
  eof { continue; }
  "password:"
}
 
1 members found this post helpful.
Old 03-15-2018, 04:37 PM   #6
cj_cheema
Member
 
Registered: Mar 2006
Location: INDIA
Distribution: RedHat, SuSE, Debian
Posts: 166

Original Poster
Rep: Reputation: 15
Hi Keefaz

Thanks for your response after your code issue is fixed, now my expect script is ignoring the unresponsive hosts.

Quote:
spawn ssh -o ...
expect {
timeout { continue; }
eof { continue; }
"password:"
}
Whenever I stuck LQ always prove me as a saviour.

Regards
Charanjit
 
Old 03-15-2018, 11:22 PM   #7
Turbocapitalist
Senior Member
 
Registered: Apr 2005
Distribution: Linux Mint, Devuan, OpenBSD
Posts: 3,351
Blog Entries: 3

Rep: Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478Reputation: 1478
Quote:
Originally Posted by cj_cheema View Post
now my expect script is ignoring the unresponsive hosts.
Where are you stuck on getting the key-based authentication working?

As mentioned above in the earlier, I would like to track down the website that is steering people to use expect instead of keys. Without keys and with StrictHostKeychecking set to "no" your remote machines are 100% vulnerable to complete capture and compromise, should anyone try. That makes them a liability to the rest of us here.

So, again, please say how you ended up trying expect instead of using SSH keys. If there is a link to the guide, please post it, so we can contact the author.
 
1 members found this post helpful.
Old 03-16-2018, 03:03 AM   #8
jlinkels
LQ Guru
 
Registered: Oct 2003
Location: Bonaire, Leeuwarden
Distribution: Debian /Jessie/Stretch/Sid, Linux Mint DE
Posts: 5,183

Rep: Reputation: 1017Reputation: 1017Reputation: 1017Reputation: 1017Reputation: 1017Reputation: 1017Reputation: 1017Reputation: 1017
Please use CODE tags instead of QUOTE tags. We want to read your code, not guess it.

The solution is fine, but it does not prevent your script from crashing when something is wrong with communication. That is, if anything goes wrong in communication after the connection has been established, you script will crash anyway.

It is recommended that you enclose code parts which can cause a crash in a catch statement. Below the catch statement is to protect a file open operation which might fail. Normally Expect crashes on a failure, inside a catch statement it will continue.
Code:
if { [catch {open $someFile w} fid] } {
    puts stderr "Could not open $someFile for writing\n$fid"
    exit 1
}
https://www.tcl.tk/man/tcl8.4/TclCmd/catch.htm

So you would put the communication statements, or anything which could cause a crash, inside the catch {} statement.

jlinkels
 
  


Reply

Tags
expect, tcl


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem running an Expect script within a Bash script mbeipi Programming 9 02-10-2018 05:00 AM
ssh to multiple host - expect script rd700 Linux - Networking 6 11-24-2015 05:24 AM
Issue in running commands in expect script from shell script yadvinder Programming 0 05-31-2012 04:07 AM
Firefox ; How to enable "Stop Unresponsive Script" theKbStockpiler Linux - General 1 12-25-2011 02:07 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:33 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration