08-17-2009 12:40 PM - edited 03-10-2019 04:44 AM
This Expect script provides expect with a list of IP addresses to Cisco IPS sensors and commands to configure Cisco IPS sensors.
I'm having 2 problems:
1. Sometimes the script appears to send the next command before the next prompt appears in which case the correct command is skipped and the one afterwards sent and accepted. The commands usually need to be entered in order so this usually produces an error. Is using a sleep timer the only or best solution to this problem?
2. From what I can tell if I don't quote the command "configure terminal" it's received as 2 separate commands so I have to quote it. I don't know if this is causing the problem but for some reason when I use this script the regex string 10\.1\.1\.100 ends up being sent without the backslashes 10.1.1.100 but I don't want the regular expression dot . evaluated I just want an IP address with periods. Something about my expect script is causing this problem because when I log in using ssh and copy and paste the commands into the IPS sensors manually the regex string is saved with the backslashes. I've tried removing the quotes and I've also tried double quoting and neither work. Does anyone know what I'm doing wrong here or what I could try?
#!/usr/bin/expect
log_user 1
set timeout 10
set user "user"
set password "password"
set ip_list {
10.1.1.10
10.1.2.10
10.1.3.10
10.1.4.10
}
set cmd_list {
"configure terminal"
"service signature-definition sig0"
"signatures 60000 0"
"alert-severity high"
"sig-fidelity-rating 100"
"sig-description"
"sig-name Foo"
"sig-string-info Foo"
"no sig-comment"
"exit"
"engine string-tcp"
"regex-string 10\.1\.1\.100"
"service-ports 0-65535"
"direction from-service"
"exit"
"exit"
"exit"
}
foreach ip $ip_list {
if {$ip != ""} {
# Connect
spawn ssh $user@$ip
expect "?assword*"
send "$password\r"
set prompt "(Foo#)"
foreach command $cmd_list {
if {$command != ""} {
expect -re $prompt {
send "$command\r"
sleep 5
}
}
}
expect -re "Apply Changes" {
send -- "yes\r"
}
expect -re $prompt {
send -- "exit\r"
}
close
}
}
send_user "\nDone.\n"
08-17-2009 01:31 PM
You have an issue with the prompt as you are hard coding the prompt to (Foo)# for every sensor ip address. I would think the expect would timeout and exit before sending next command. I suggest changing the prompt to
If you don't double quote the config terminal, foreach loop will consider config and terminal as separate entries in the cmd_list and hence send separately.
For regex-string 10\.1\.1\.100 did you try sending as 10.1.1.100 without backslash (as the string is already enclosed in double quotes)
08-17-2009 03:31 PM
@mkodali
Thanks for your reply. I scrubbed the script of all real user names, passwords, IP addresses, regex, sensor names at prompts, etc.
I changed the regex I use to match the naming scheme for the IPS sensors to Foo# because I don't want anyone to see it.
This script works as far as the prompt goes. This script will successfully log into every sensor and send commands to every sensor.
On a few problematic sensors for some reason after sending "service signature-definition sig0", that seems to be the most common command causing this problem, the sensor takes a very long time such as 5-10 seconds before it provides another prompt. This long delay is why I'm using a sleep timer. The problem with that is my sleep timer is inside the loop which means if I set it to 10 seconds the script waits 10 seconds between every command on every sensor. What I don't understand is I thought expect was supposed to wait for a prompt before sending the command so I don't understand why I'm having to use a sleep timer at all but then that's why I'm on here. I'm missing something :)
I want the backslash
If I understand regex correctly the regex string 10.1.1.100 would match 10n1n1n100
I just tested it and it does
With the backslash the regex string 10\.1\.1\.100 matches only 10.1.1.100 and that's what I want.
08-17-2009 07:37 PM
Now I understand your problem better.
By default I think expect gives up after 10 seconds waiting for the prompt. For the first issue try changing the timeout to some value like 240 seconds by using the command "set timeout 240" before the foreach loop. Remove the sleep command in the loop before you run the script.
set timeout 240
foreach command $cmd_list {
if {$command != ""} {
expect -re $prompt {
send "$command\r"
}
}
You can set it back to 10 seconds after the loop.
For the second issue escape the backslash character itself :
"engine string-tcp"
"regex-string 10\\.1\\.1\\.100"
Hope this will solve your problems.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide