How to send escape characters through Expect http://mini.net/tcl/3038
How to send escape characters through Expect http://mini.net/tcl/201
Expect Send Function Keys
Function Keys, Escape Sequences, in expect
Esc+9
send \0339
Esc+A
send \033A
F9
send ???
Up
Down
send — “^[\[B”
(Please note that the ^[ is the escape character, which is one character, and not two separate characters(not ^ and [). I’m not sure how to generate this inside of vi, so I just copy and paste it. You can do this to get it in your file: echo -e “\033” >> myfile.exp)
Left
Right
We have also found that some implementations, such as over a serial port, may require a moment of silence after sending an escape sequence. When we sent multiple escape sequences back to back in one situation (speaking to a BIOS over the serial port) that the BIOS would refuse the escape sequences.
You can determine this same info by doing the following:
run “od -c”
Press the key you are interested in followed by the return key followed by Ctrl+D.
You should then see the following output (we pressed the down arrow here):
[user@localhost user]$ od -c ^[[B 0000000 033 [ B \n 0000004 [user@localhost user]$
So we want everything between the 0000000 and the \n, and you have to escape the left bracket for expect so it doesn’t think you are giving it a system command.
Here’s some ascii tables if you need more help: http://www.jimprice.com/jim-asc.shtml
SSH AutoLogin
I would like this to be a bit cleaner in expect, but I’m not an expert at writing expect scripts. Nevertheless, this script runs just as well. For more notes on SSH autologin (using an identity key) see sshkeys.html. If anyone would care to clean this up so there is less duplicated code, I would really appreciate it.
The one special character you see below is CTRL+D which usually translates to either logout or exit. You can get this character in the editor on a linux box by typing ctrl+v ctrl+d (in insert mode).
This program accepts command line arguments. The arguments are the commands you want run on the destination box. Right now I have the ipaddress fixed in this script. Later I would add something so I could pass the ip address of the destination box. Also you can pass several commands to run on the remote box by separating them with a semicolon. The semicolon and pipe commands will need to be escaped so your own shell doesn’t interpret and use the semicolon.
Here’s a sample calling with 3 commands and a pipe command to be run on the remote box:
./script.exp ls \; /sbin/ifconfig \| grep inet \; ls /
#!/usr/bin/expect -f # # This Expect script was generated by autoexpect on Tue Mar 18 15:38:55 2003 # Expect and autoexpect were both written by Don Libes, NIST. # # Note that autoexpect does not guarantee a working script. It # necessarily has to guess about certain things. Two reasons a script # might fail are: # # 1) timing - A surprising number of programs (rn, ksh, zsh, telnet, # etc.) and devices discard or ignore keystrokes that arrive "too # quickly" after prompts. If you find your new script hanging up at # one spot, try adding a short sleep just before the previous send. # Setting "force_conservative" to 1 (see below) makes Expect do this # automatically - pausing briefly before sending each character. This # pacifies every program I know of. The -c flag makes the script do # this in the first place. The -C flag allows you to define a # character to toggle this mode off and on. set force_conservative 0 ;# set to 1 to force conservative mode even if ;# script wasn't run conservatively originally if {$force_conservative} { set send_slow {1 .1} proc send {ignore arg} { sleep .1 exp_send -s -- $arg } } # # 2) differing output - Some programs produce different output each time # they run. The "date" command is an obvious example. Another is # ftp, if it produces throughput statistics at the end of a file # transfer. If this causes a problem, delete these patterns or replace # them with wildcards. An alternative is to use the -p flag (for # "prompt") which makes Expect only look for the last line of output # (i.e., the prompt). The -P flag allows you to define a character to # toggle this mode off and on. # # Read the man page for more info. # # -Don #set DO_TASK "wget ftp://172.16.0.4/pub/tests/testme.sh; sh ./testme.sh >stdout.log 2>stderr.log; (echo stderr; cat stderr.log; echo stdout; cat stdout.log) | mail -s testing riblack@mydomain.net; rm -f ./testme.sh\r" if { "x$argv" == "x" } { send_user "\nPlease specify command to run.\r\n" exit 1 } catch {set DO_TASK "$argv\r"} regsub -all {\{} $DO_TASK {} DO_TASK regsub -all {\}} $DO_TASK {} DO_TASK if { "x$DO_TASK" == "x" } { send_user "\nSorry, DO_TASK died.\r\n" exit 1 } set timeout -1 spawn $env(SHELL) match_max 100000 expect "*\]\$ " send -- "ssh root@172.32.0.243\r" expect { "The authenticity of host '172.32.0.243 (172.32.0.243)' can't be established.\r RSA key fingerprint is *.\r Are you sure you want to continue connecting (yes/no)? " { send -- "yes\r" expect "yes\r Warning: Permanently added '172.32.0.243' (RSA) to the list of known hosts.\r\r" expect { "root@172.32.0.243's password: " { send -- "password\r" expect "Last login: *\r\r *root\]# " send "wget ftp://172.16.0.4/pub/tests/id_dsa.pub; mkdir -p ~/.ssh; cat id_dsa.pub >> ~/.ssh/authorized_keys2; rm -f id_dsa.pub\r" expect "*root\]# " send -- "$DO_TASK" expect "*root\]# " send -- "" expect "logout\r *Connection to 172.32.0.243 closed.\r\r *\]\$ " send -- "" expect eof } "Last login: *\r\r *root\]# " { send -- "$DO_TASK" expect "*root\]# " send -- "" expect "logout\r *Connection to 172.32.0.243 closed.\r\r *\]\$ " send -- "" expect eof } } } "root@172.32.0.243's password:" { send -- "password\r" expect "Last login: *\r\r *root\]# " send -- "$DO_TASK" expect "*root\]# " send -- "" expect "logout\r *Connection to 172.32.0.243 closed.\r\r *\]\$ " send -- "" expect eof } "Last login: *root\]# " { send -- "$DO_TASK" expect "*root\]# " send -- "" expect "logout\r *Connection to 172.32.0.243 closed.\r\r *\]\$ " send -- "" expect eof } "Host key verification failed." { send -- "cat ~/.ssh/known_hosts | grep -v 172.32.0.243 > ~/.ssh/known_hosts1; mv ~/.ssh/known_hosts1 ~/.ssh/known_hosts; ssh root@172.32.0.243\r" exp_continue } }