The following expect / code pair only works sometimes:
Simple cpp echo program:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string buffer;
while (1)
{
getline(cin, buffer, '\n');
if (cin.eof())
break;
cout<<buffer<<endl;
}
return 0;
}
Expect script
#!/usr/bin/expect
spawn ./echo
exp_internal 1
set timeout 1
send "a\n"
expect {
-re {^a\r\n$}
}
Success match:
spawn ./echo
send: sending "a\n" to { exp6 }
Gate keeper glob pattern for '^a\r\n$' is 'a
'. Activating booster.
expect: does "" (spawn_id exp6) match regular expression "^a\r\n$"? Gate "a\r\n"? gate=no
a
expect: does "a\r\n" (spawn_id exp6) match regular expression "^a\r\n$"? Gate "a\r\n"? gate=yes re=yes
expect: set expect_out(0,string) "a\r\n"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "a\r\n"
Failure match:
spawn ./echo
send: sending "a\n" to { exp6 }
Gate keeper glob pattern for '^a\r\n$' is 'a
'. Activating booster.
expect: does "" (spawn_id exp6) match regular expression "^a\r\n$"? Gate "a\r\n" gate=no
a
a
expect: does "a\r\na\r\n" (spawn_id exp6) match regular expression "^a\r\n$"? Gate "a\r\n"? gate=yes re=no
expect: timed out
I don't understand why on some runs I get the double line "a", and some runs I get the single one? I would have assumed the expect hooks up spawned process such that send will pipe everything to stdin and expect gets everything from stdout.
Any clarifications would be appreciated.
It is because your tty have echo enabled. In your first case you send a\n and your program read it and return a\n but expect did read before std::cout is flushed so the buffer contain only a\n. In the other case it read and send didn't finished so it read nothing and the second run it does read and your std::cout was flushed before. So you read two times. You could modify your program to output something else (like with a prefix) or add a dummy expect "<non existing string>" as last instruction so you force to drain stdout.
$ ./expect.sh
spawn ./echo
send: sending "a\n" to { exp6 }
Gate keeper glob pattern for '^a\r\n$' is 'a
'. Activating booster.
expect: does "" (spawn_id exp6) match regular expression "^a\r\n$"? Gate "a\r\n"? gate=no
a
expect: does "a\r\n" (spawn_id exp6) match regular expression "^a\r\n$"? Gate "a\r\n"? gate=yes re=yes
expect: set expect_out(0,string) "a\r\n"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "a\r\n"
expect: does "" (spawn_id exp6) match glob pattern "<non existing string>"? no
a
expect: does "a\r\n" (spawn_id exp6) match glob pattern "<non existing string>"? no
expect: timed out
To fix the root cause you can first disabling echo with stty -echo and then spawn with option -nottyinit used like this spawn -nottyinit ./echo because
-nottyinit skips the "sane" initialization
An alternative way is to set set stty_init -echo then spawn
https://github.com/aeruder/expect/blob/ce11b8121e6900888d137fec0b990bd1484cbb7c/pty_unicos.c#L147-L155 here is where tty is setup. stty_init is applied after tty sane. So it might be a preferred method.
Related
I've been struggling with getting the output from a remote server to a local variable or a local file.
My attempt:
#!/bin/bash
my_pass=!!psw!!
server=10.10.10.10
/usr/bin/expect << ENDOFEXPECT
exp_internal 1 ;# expect internal debugging. remove when not needed
set PROMPT ":~ ?# ?"
set timeout 30
spawn bash -c "ssh root#$server"
expect "assword:"
send "$my_pass\r"
expect -re "$PROMPT"
send -- "df -kh /\r"
expect -re "df\[^\n]+\n.+\n(.+\r\n.+)\r\n"
set command_output $expect_out(1,string)
send_user "$command_output\r"
interact
ENDOFEXPECT
echo "====================="
echo " >> $command_output"
Output:
spawn bash -c ssh root#10.10.10.10
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {154725}
expect: does "" (spawn_id exp4) match glob pattern "assword:"? no
Password:
expect: does "\rPassword: " (spawn_id exp4) match glob pattern "assword:"? yes
expect: set expect_out(0,string) "assword:"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "\rPassword:"
send: sending "!!psw!!\r" to { exp4 }
Gate keeper glob pattern for '' is ''. Not usable, disabling the performance booster.
expect: does " " (spawn_id exp4) match regular expression ""? (No Gate, RE only) gate=yes re=yes
expect: set expect_out(0,string) ""
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) ""
send: sending "df -kh /\r" to { exp4 }
Gate keeper glob pattern for 'df[^
]+
.+
(.+
.+)
' is ''. Not usable, disabling the performance booster.
expect: does " " (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
expect: does " \r\n" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
Last login: Fri Dec 2 23:58:09 2022 from 10.10.10.1
Welcome to server image 2.2
expect: does " \r\nLast login: Fri Dec 2 23:58:09 2022 from 10.10.10.1\r\r\n\r\nWelcome to server image 2.2\r\n\r\n" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
REMY_SERVER:~ #
expect: does " \r\nLast login: Fri Dec 2 23:58:09 2022 from 10.10.10.1\r\r\n\r\nWelcome to server image 2.2\r\n\r\n\u001b[?1034h\u001b[1m\u001b[31mREMY_SERVER:~ # \u001b(B\u001b[m" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
expect: timed out
interact: received eof from spawn_id exp0
=====================
>>
Expected:
What I ultimately want is to get the output of df -kh into a local variable or even better, append it directly to a local file (on the local machine, not the server on which the command is executed) so that it contains something like:
$ cat ./result.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 20G 18G 1,7G 92% /
Method 1: The proper way is to not use expect and use key pair access :
Step #1
Setup a SSH key pair (google it) and then copy the SSH key to the remote server. To do this I'd recommend using ssh-copy-id.
Step #2
Now with the ability to SSH to a server in place using a key, your above problem turns into this:
$ ssh root#10.10.10.10 "df -kh"
You can get fancy and use here documents (heredocs aka. here-docs) to further enhance this technique.
$ ssh root#10.10.10.10 <<EOF
> df -kh
> EOF
or put the commands in a file and pass them to ssh:
$ ssh root#10.10.10.10 < my.cmds
Method 2: Expect
See the following, expains how to use it properly and a tool to create expect scripts
https://hostadvice.com/how-to/how-to-automate-tasks-in-ssh/
First, your PROMPT regex is not matching. I see the output has some colour codes in it:
expect: does " \r\nLast login: ...REMY_SERVER:~ # \u001b(B\u001b[m" (spawn_id exp4) match regular expression ...
It's good to anchor prompt regexes, and to enclose them in braces. Try
set PROMPT { # \S*$}
Or, assuming the login shell is bash, set a new prompt that's easier to match:
send "$my_pass\r"
expect "Welcome to server"
send -- "PS1='>'\r"
set PROMPT {>$}
expect -re $PROMPT
Next, the relevant code for the question.
send -- "df -kh /\r"
expect -re "df\[^\n]+\n.+\n(.+\r\n.+)\r\n"
set command_output $expect_out(1,string)
send_user "$command_output\r"
I'd adjust your regex a touch:
set cmd "df -kh /"
send -- "$cmd\r"
expect -re "$cmd\r\n(.+)\r\n.*$PROMPT"
Then you're capturing and "echoing" the result correctly
set command_output $expect_out(1,string)
send_user "$command_output\n"
# use a newline here ......^
And to append it to a local file:
set fh [open ./results.txt a]
puts $fh $command_output
close $fh
I need to get a dataset from a telnet shell, for this I have looked at expect https://www2.lib.uchicago.edu/keith/tcl-course/topics/expect.html
This is my expect script:
/usr/bin/expect -d << EOD
spawn telnet myhost
log_user 1
set timeout 10
expect "Login:"
send "user\n\r"
expect "Password:"
send "password\n\r"
expect "*$*"
send "AT\n\r"
expect "OK"
send "AT&CSR\n"
expect "OK"
send "AT!G=A6\n"
expect "OK"
send "AT^MI=0\n"
expect "OK"
send "AT^SX=0\n"
expect "OK"
send "AT^SR=0,1"
expect "*$*"
send "exit\r"
Now I can connect to the remote host, send command, but cannot read the results, here a shell result:
> expect: does " " (spawn_id exp4) match glob pattern "*"? yes expect:
> set expect_out(0,string) " " expect: set expect_out(spawn_id) "exp4"
> expect: set expect_out(buffer) " " send: sending "AT\n\r" to { exp4 }
>
> expect: does "" (spawn_id exp4) match glob pattern "OK"? no
> ********
>
> OK
>
> expect: does "********\r\n\r\nOK\r\n" (spawn_id exp4) match glob
> pattern "OK"? yes expect: set expect_out(0,string) "OK" expect: set
> expect_out(spawn_id) "exp4" expect: set expect_out(buffer)
> "********\r\n\r\nOK" send: sending "AT&CSR\n" to { exp4 }
>
> expect: does "\r\n" (spawn_id exp4) match glob pattern "OK"? no AT
>
> expect: does "\r\nAT\r\n" (spawn_id exp4) match glob pattern "OK"? no
>
> OK
>
> expect: does "\r\nAT\r\n\r\nOK\r\n" (spawn_id exp4) match glob pattern
> "OK"? yes expect: set expect_out(0,string) "OK" expect: set
> expect_out(spawn_id) "exp4" expect: set expect_out(buffer)
> "\r\nAT\r\n\r\nOK" send: sending "AT!G=A6\n" to { exp4 }
>
> expect: does "\r\n" (spawn_id exp4) match glob pattern "OK"? no AT&CSR
> expect: does "\r\nAT&CSR" (spawn_id exp4) match glob pattern "OK"? no
> AT!G=A6 expect: does "\r\nAT&CSRAT!G=A6" (spawn_id exp4) match glob
> pattern "OK"? no expect: timed out send: sending "AT^MI=0\n" to { exp4
> }
>
> expect: does "\r\nAT&CSRAT!G=A6" (spawn_id exp4) match glob pattern
> "OK"? no AT^MI=0
If the result of the command doesn't match the expected it goes to next command, is there a way to catch the response result?
EDIT:
I tried to simplify thing and added interact, without no luck:
/usr/bin/expect -d << EOD
> spawn telnet myhost
> log_user 1
> interact"
> EOD
expect version 5.45.4
argv[0] = /usr/bin/expect argv[1] = -d
set argc 0
set argv0 "/usr/bin/expect"
set argv ""
executing commands from command file
spawn telnet myhost
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {11306}
invalid command name "interact""
while executing
"interact""
The way you send your AT commands is wrong.
According to ETSI specification 127.007, by default AT commands are terminated by \r (IRA 13 - ASCII carriage return) character[1]. For further details, see paragraph "4.1 - Command line".
In order to fix your issue, just send AT\r instead of AT\n\r, AT&CSR\r instead of AT&CSR\n and so on (the latter is a mistake you repeated for every following AT command). Otherwise the AT parser won't recognize your commands correctly.
[1] Command line termination character can be customized by means of ATS3 command, with the following syntax:
ATS3=<value>
Where <value> is the decimal ASCII value of the new command line termination character (default is 13).
I'm writing an expect file to connect to handle the interaction with the remote device by using a script that looks something like the following, and I am facing a few problems with it. Mainly, when I run the script stand-alone or interactively (on a runner), it works as I wish, but when I plug in the code for a testing using the Gitlab CI on one of the runners, it has the following problems:
the command spawn /usr/bin/scp $rsaFile
remote:/var/root/id_rsa.pub doesn't seem to show up in the CI log
(though the first spawn /usr/bin/ssh remote command shows up) - I
suspect it's not being called at all.
The same spawn command persistently gives me the following message until the script stops executing at the next interact command: "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\n"
interact complains that spawn id exp0 not open (which I assume may be because scp command not working properly)
Here's the code:
spawn /usr/bin/ssh remote
expect {
-re ".*assword:.*" {
exp_send "password\r";
exp_continue
}
-re ".*sh.*" {
exp_send "mount -uw /\r";
exp_send "nvram -somecommand"
exp_send "exit\r"
}
}
interact
# Copy over the key
set rsaFile "/var/root/Resources/id_rsa.pub"
spawn /usr/bin/scp $rsaFile remote:/var/root/id_rsa.pub;
expect {
# 1&2 were added to the original script for debugging purposes
-re "^id_rsa.pub.*" { #1: output I'd expect in case of successful scp
exp_send "exit\r"
}
-re ".*assword:.*" {
exp_send "password\r";
exp_send "exit\r"
}
-re "Warning:.*Warning.*Warning.*" { #2: to debug the expect hanging
exp_send "exit\r"
}
}
interact;
Here's the error msg (expect is on debug mode):
spawn /usr/bin/ssh remote
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {24373}
Gate keeper glob pattern for '.*assword:.*' is '*assword:*'. Activating booster.
Gate keeper glob pattern for '.*sh.*' is '*sh*'. Activating booster.
expect: does "" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no
".*sh.*"? Gate "*sh*"? gate=no
Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.
expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\n" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no
".*sh.*"? Gate "*sh*"? gate=no
root#fe80::cccc:48ff:fe33:3344%en4's password:
expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nroot#fe80::cccc:48ff:fe33:3344%en4's password: " (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=yes re=yes
expect: set expect_out(0,string) "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nroot#fe80::cccc:48ff:fe33:3344%en4's password: "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nroot#fe80::cccc:48ff:fe33:3344%en4's password: "
send: sending "password\r" to { exp6 }
expect: continuing expect
expect: does "" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no
".*sh.*"? Gate "*sh*"? gate=no
expect: does "\r\n" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no
".*sh.*"? Gate "*sh*"? gate=no
expect: does "\r\n\u001b[?1034h" (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no
".*sh.*"? Gate "*sh*"? gate=no
-sh-3.2#
expect: does "\r\n\u001b[?1034h-sh-3.2# " (spawn_id exp6) match regular expression ".*assword:.*"? Gate "*assword:*"? gate=no
".*sh.*"? Gate "*sh*"? gate=yes re=yes
expect: set expect_out(0,string) "\r\n\u001b[?1034h-sh-3.2# "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\r\n\u001b[?1034h-sh-3.2# "
send: sending "mount -uw /\r" to { exp6 }
send: sending "nvram -some-command" to { exp6 }
send: sending "exit\r" to { exp6 }
interact: received eof from spawn_id exp0
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {24376}
Gate keeper glob pattern for '^id_rsa.pub.*' is 'id_rsa?pub*'. Activating booster.
Gate keeper glob pattern for '.*assword:.*' is '*assword:*'. Activating booster.
Gate keeper glob pattern for 'Warning:.*Warning.*Warning.*' is ''. Not usable, disabling the performance booster.
expect: does "" (spawn_id exp1) match regular expression "^id_rsa.pub.*"? Gate "id_rsa?pub*"? gate=no
".*assword:.*"? Gate "*assword:*"? gate=no
"Warning:.*Warning.*Warning.*"? (No Gate, RE only) gate=yes re=no
expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\n" (spawn_id exp1) match regular expression "^id_rsa.pub.*"? Gate "id_rsa?pub*"? gate=no
".*assword:.*"? Gate "*assword:*"? gate=no
"Warning:.*Warning.*Warning.*"? (No Gate, RE only) gate=yes re=no
expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\n" (spawn_id exp1) match regular expression "^id_rsa.pub.*"? Gate "id_rsa?pub*"? gate=no
".*assword:.*"? Gate "*assword:*"? gate=no
"Warning:.*Warning.*Warning.*"? (No Gate, RE only) gate=yes re=no
expect: does "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\n\r\n\r\n\r\n" (spawn_id exp1) match regular expression "^id_rsa.pub.*"? Gate "id_rsa?pub*"? gate=no
".*assword:.*"? Gate "*assword:*"? gate=no
"Warning:.*Warning.*Warning.*"? (No Gate, RE only) gate=yes re=yes
expect: set expect_out(0,string) "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\n\r\n\r\n\r\n"
expect: set expect_out(spawn_id) "exp1"
expect: set expect_out(buffer) "Warning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\nWarning: Permanently added 'fe80::cccc:48ff:fe33:3344%en4' (ECDSA) to the list of known hosts.\r\n\r\n\r\n\r\n\r\n\r\n"
send: sending "exit\r" to { exp1 }
interact: spawn id exp0 not open
while executing
"interact"
(file "./Resources/Setup.command" line 44)
ERROR: Build failed: exit status 1
Any help would be appreciated! Thanks in advance
BTW- the problem was annoying enough for me to figure out, as this is my very first post to stack overflow. :)
Try like this:
spawn /usr/bin/ssh remote
expect {
-re ".*assword:.*" {
exp_send "password\r";
exp_continue
}
-re ".*-sh-.*" {
exp_send "mount -uw /; nvram -somecommand; exit\r"
exp_continue
}
eof {}
}
wait
set rsaFile "/var/root/Resources/id_rsa.pub"
spawn /usr/bin/scp $rsaFile remote:/var/root/id_rsa.pub;
expect {
-re ".*assword:.*" {
exp_send "password\r";
exp_continue
}
eof {}
}
wait
Your interact may fail because at that time the spawned process may have already exited and obviously it cannot interact with a dead process.
For your script, my expect eof basically have the same effect with your interact. They all wait for the spawned process to finish. The difference here is timing. And expect eof just does not generate error when the spawned process exits.
I'm trying to reboot a D-Link router by connecting to it via telnet through expect.
The problem is that I can't execute (through the expect script) any of the commands supported by the router.
First of all, I show you a short telnet session with my router:
telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
BCM96338 ADSL Router
Login: admin
Password:
> swversion show
EU_3-12-01-1R00.A2pB026.d20m
> logout
Bye bye. Have a nice day!!!
Connection closed by foreign host.
Now I'm trying to make it automatic with an Expect script but I can't make it work. Here's the script:
#!/usr/bin/expect -f
#exp_internal 1
set timeout 30
#router username
set name admin
#command to execute
set routercmd "swversion show"
#router password
set pass mypassword
#router IP address
set routerip 192.168.1.1
spawn telnet $routerip
# send username & password
expect "Login: "
send "$name\r"
expect "Password: "
send "$pass\r"
expect "> "
send "$routercmd\r"
expect "> "
When I execute the script, it gets stuck at the password prompt:
./reboot_dut.sh
spawn telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
BCM96338 ADSL Router
Login: admin
Password:
If I uncomment the #exp_internal 1 line I get:
./reboot_dut.sh
spawn telnet 192.168.1.1
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {6398}
expect: does "" (spawn_id exp7) match glob pattern "Login: "? no
Trying 192.168.1.1...
expect: does "Trying 192.168.1.1..." (spawn_id exp7) match glob pattern "Login: "? no
expect: does "Trying 192.168.1.1...\r\n" (spawn_id exp7) match glob pattern "Login: "? no
Connected to 192.168.1.1.
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1." (spawn_id exp7) match glob pattern "Login: "? no
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\n" (spawn_id exp7) match glob pattern "Login: "? no
Escape character is '^]'.
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'." (spawn_id exp7) match glob pattern "Login: "? no
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'.\r\n" (spawn_id exp7) match glob pattern "Login: "? no
BCM96338 ADSL Router
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'.\r\nBCM96338 ADSL Router\r\n" (spawn_id exp7) match glob pattern "Login: "? no
Login:
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'.\r\nBCM96338 ADSL Router\r\nLogin: " (spawn_id exp7) match glob pattern "Login: "? yes
expect: set expect_out(0,string) "Login: "
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'.\r\nBCM96338 ADSL Router\r\nLogin: "
send: sending "admin\r" to { exp7 }
expect: does "" (spawn_id exp7) match glob pattern "Password: "? no
a
expect: does "a" (spawn_id exp7) match glob pattern "Password: "? no
dmin
Password:
expect: does "admin\r\nPassword: " (spawn_id exp7) match glob pattern "Password: "? yes
expect: set expect_out(0,string) "Password: "
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "admin\r\nPassword: "
send: sending "mypassword\r" to { exp7 }
expect: does "" (spawn_id exp7) match glob pattern "> "? no
expect: timed out
send: sending "swversion show\r" to { exp7 }
expect: does "" (spawn_id exp7) match glob pattern "> "? no
> swversion show
expect: does "\r\n> swversion show\r\n" (spawn_id exp7) match glob pattern "> "? yes
expect: set expect_out(0,string) "> "
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "\r\n> "
SOLUTION: I found the solution to the problem. The router I was trying to reboot was a D-LINK 2640B. A working expect script for this router is:
#!/usr/bin/expect -f
spawn telnet ROUTER_IP
match_max 10000
expect *login:*
sleep 2
send -- "USERNAME\r"
expect *assword:*
sleep 2
send -- "PASSWORD\r"
expect *>*
send -- "\r"
expect *>*
send -- "COMMAND\r"
expect *>*
send -- "\r"
expect *>*
send -- "logout\r"
I'd say you need to match your prompt to ">", as opposed to "> " (i.e. no space after it).
I have the simplest script ever:
#!/usr/bin/expect
expect "hello"
send -- "ll \r"
When I run it, I manually type "hello" word and that ll command never runs ...
Afterwards I put exp_internal 1 and then this comes up
[root#localhost tmp]# ./file1.exp
expect: does "" (spawn_id exp0) match glob pattern "hello"? no
hello
expect: does "hello\n" (spawn_id exp0) match glob pattern "hello"? yes
expect: set expect_out(0,string) "hello"
expect: set expect_out(spawn_id) "exp0"
expect: set expect_out(buffer) "hello"
}end: sending "ll \r" to { exp0 ll
[root#localhost tmp]#
Can anyone explains me why the command is not being ran as command ?