Expect script too fast: add a sleep between each line read from a file
So, older discussion but after wrestling with expect
over the past day or two and gathering several helpful hints from users here and elsewhere I decided to post what I had found. I am also on a Mac not native Linux for this so some things were quirky.
This script is called from a bash
script with:
expect -d <filename>.expect
If #!<PATH to expect> -f
is implemented in the top line of your *.expect
file AND you:
chmod +x <filename>.expect
your file this will work.
The -d
is for additional debug info.
Call expect
with:
expect -df <filename>.expect
in your bash script to accomplish the same effect and you do not need executable rights on the file.
The debug info is very helpful on seeing your expect
statements, variables, etc. like this:
spawn <program> <args>
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {29747}
expect: does "" (spawn_id exp10) match glob pattern "Please enter
passphrase:"? no
Please enter passphrase:
expect: does "Please enter passphrase: " (spawn_id exp10) match glob
pattern "Please enter passphrase:"? yes
expect: set expect_out(0,string) "Please enter passphrase:"
expect: set expect_out(spawn_id) "exp10"
expect: set expect_out(buffer) "Please enter passphrase:"
Here is the short bash script, (only an example, but helpful if you need it to do more complex stuff or just call it from bash
for some reason)
#!/bin/bash
expect -d exp.expect "$WORD"
RET=$?
if [ $RET -eq 1 ]; then
#mac specific, sheer laziness, allows me to do other stuff...
#use esay or similar on Linux
say "Query was found, expect returned success"
echo ***************************************************
echo ******************FOUND!***************************
fi
exit 0
Here is the expect
script:
#!/usr/bin/expect -f
#capture logs for debugging
log_file -a log_file.txt
#dont timeout, let the program run its course, (was mandatory for me)
set timeout -1;
#capture all of our output for debugging
set output [ open "output.txt" "RDWR" ];
#This procedure is called repeatedly with the next word
proc check_word {w} {
#kickoff our other program we are going to talk to
spawn <program> <args>
#we want this one to go regardless, the next 2 are mutex
expect "Please enter passphrase:" { send "$w\r"; send_user "\nSENDING: $w\r"; send_user "\nOutput BUFFER: $expect_out(buffer)\n" }
#These are mutually exclusive, either worked or not, can be grouped
expect {
"scrypt: Passphrase is incorrect" { send_user "\n*FAILED*\n"; close }
-re {anders} { send_user "$expect_out(buffer)\n"; close; exit 1 }
}
#wait for the process to end, timeout is set to never expire
wait
}
#open the file to take the words from, (happens before proc above)
set input [ open "words.txt" "RDONLY" ];
#while there are still words, (we exit on a match) ...keep going....
while {[gets $input word] != -1} {
check_word $word;
}
#close input file, TODO do this upon success in expect call too?
close $input
close $words
#EOF
Hopefully this helps some/anyone save some time out there!
Use a while
loop:
set fp [open "datfile"]
while {[gets $fp line] >= 0} {
puts $line
#sleep 3
# but better to wait for the prompt
expect #
}