Expect script not sending command - expect

I am using expect to deal with an embedded system's U-boot.
However, my script is not sending command at certain point.
Here is my script
#!/usr/bin/expect
set scriptaddr "0x32000000"
spawn screen /dev/ttyUSB1 115200
expect "Hit any key to stop autoboot:"
send "\r"
puts "Start flashing"
send "tftp $scriptaddr recovery_files/install.scr \r"
sleep 2
send "source 0x32000000\r"
## here start the flashing process which takes 15 mins
## this is the part where not working ##
expect "(Please reset your board)"
sleep 3
send "reset\r"
And this is the last part showing at the console which waiting user to key in "reset"
#################################################################
#################################################################
###
2 MiB/s
done
Bytes transferred = 7333121 (6fe501 hex)
Uncompressed size: 168820224 = 0xA0FFE00
MMC write: dev # 0, block # 3940352, count 329727 ... 329727 blocks written: OK
============ INSTALLATION IS DONE =============
(Please reset your board)
machine#
Any mistake i have made? Please assist, thank you!

By default expect will have a 10seconds timeout.
Solution : set timeout <time in second>

Related

expect script capturing garbage characters - need to remove

I have a switch I'm trying to write to grab output from a hp switch. The source machine is an ubuntu 18.04. The code version on the switch is 16.04. I tried changing the terminal settings on the switch from the default of vty100 to ansi and none but no difference. How do I get rid of the extra special characters show below?
set timeout 20
spawn ssh -l manager 192.168.10.10
expect "manager#192.168.10.10's password:"
send "admin\n"
expect "Press any key to continue"
send "j\n"
log_file -a hp.log
send "show vlan 10\n"
expect "labswitch#"
send "conf\n"
send "hostname newswitch\n"
expect "newswitch#"
send "exit\n"
expect "newswitch#"
send "logout\n"
I have this extra output of characters through each part of the script in the log file and the console. Need to remove these characters from output. ??
^[[?6l^[[1;30r^[[?7h^[[2J^[[1;1H^[[1920;1920H^[[6n^[[1;1HYour previous successful login (as manager) was on 2019-03-07 $ from 192.168.10.4
^[[1;30r^[[30;1H^[[30;1H^[[2K^[[30;1H^[[?25h^[[30;1H^[[30;1labswitch# ^[[30;1H^[[30;11H^[[30;1H^[[?25h^[[30;11H^[[1;0H^$ Status and Counters - VLAN Information - VLAN 10
VLAN ID : 10
Name : Server_Lab
Status : Port-based
Voice : No
Jumbo : Yes
Private VLAN : none
Associated Primary VID : none
Associated Secondary VIDs : none
Port Information Mode Unknown VLAN Status
---------------- -------- ------------ ----------
11 Tagged Learn Up
12 Tagged Learn Up
^[[1;30r^[[30;1H^[[30;1H^[[2K^[[30;1H^[[?25h^[[30;1H^[[30;1H
Those are ANSI Escape sequences
You should be able to strip them out of the log file with:
send "logout\r" ;# idiomatically, use \r to "hit enter"
log_file ;# turn off logging
# read the log file
set fid [open hp.log r]
set contents [read -nonewline $fid]
close $fid
# remove the escape sequences
regsub -all {\033\[(?:\?|\d+;)?\d+[[:alpha:]]} $contents {} stripped
# write the new contents
set fid [open hp.log w]
puts $fid $stripped
close $fid

expect telnet - command not executing

I am struggling with executing command via telnet/expect.
set send_slow {500 .5}
send -s -- "show slot *\r"
expect {
".*>" {
send -s -- "y\r"
exp_continue
}
".*#\s"
}
send -s "who\r"
expect "# "
send -s "alm\r"
expect "# "
send -s -- "logout\r"
show slot command prints card in slots. Due to paging user is asked to continue. After execution that a prompt NODE2-1# is shown and I want to execute command who.
What I get is:
2/36 PF Empty Up Down UEQ
2/37 FAN FAN Up Up
2/38 Empty Empty Down Down UAS UEQ
2/39 Empty Empty Down Down UAS UEQ
25/1 SFD40 SFD40 Up Up
Node2-1#<br> Node2-1# who
Session Username Date Terminal
-------------------------------------------------------------------------------
116 (cli tel) * admin May 29 06:57 XX.X.XX.XX
Node2-1# almlogout
Alarm Status: Critical-3 Major-0 Minor-0
As you can see, first prompt is left empty and in second one there is a command. It takes few seconds to execute it.
Moreover, below one can see, that in prompt there is pasted command almlogout. These two are separate commands -> alm and logout. However, they are pasted together.
Question is - how to execute command in prompt without that delay, and second - how to separate two commands
By default, expect statement's pattern is in glob style so ".*>" should be -re ".*>" and ".*#\s" should be -re ".*#\\s" or -re {.*#\s} ("\s" is actually "s").
And since .* can match nothing, so -re {.*>} is the same as -re {>} and -re {.*#\s} the same as -re {#\s}.

How to grab 'show tech' with bash and expect?

I'm using 2 scripts. A bash and an expect script. the bash is just a for loop with a set of IPs. If I can, I would use the expect script to create a variable near the beginning, right after login. It would look for the hostname, assign it to a variable, then use that variable as the 'match' after show tech output.
Also, the IPs are example. I'm not actually expecting (no pun intended) this to operate on public DNS IPs. Ok ok, you got me, I put this disclaimer here just so I could 'not' make that pun.
#!/bin/bash
arrayHOST+=( '8.8.8.8' '8.8.4.4' '4.2.2.2' '4.2.2.1' )
username="user1"; password="pass1"
for host in ${arrayHOST[#]}; do
./expect.sh $host $username $password >> $host.txt
done
and the expect script:
#!/usr/bin/expect -f
#log_user 0
set timeout -1
set varIP1 [lindex $argv 0]
set varUSER [lindex $argv 1]
set varPASS [lindex $argv 2]
spawn telnet $varIP1
expect "Username:"
send "$varUSER\r"
expect "Password:"
send "$varPASS\n"
expect "#"
send "term leng 0\r"
expect "#"
send "term wid 0\r"
expect "#"
send "show tech\r"
expect "#"
puts $expect_out(buffer);
Problem is that there are '#' characters that match before the command finishes so I don't get to capture the whole thing. Points to consider:
The end of the output from 'show tech' isn't the same on every device in the IP list unless you consider the hostname of the device itself.
Yes, I know I can "show tech | redirect tftp:// etc". This wont help me achieve the desired results.
I've tried 'not expecting anything' but this causes expect to not capture anything. (sending show tech without following with a new line containing expect "#" or anything else)
spawn telnet 8.8.8.8
Trying 8.8.8.8...
Connected to 8.8.8.8.
Escape character is '^]'.
User Access Verification
Username: benjamin
Password:
rowtar#term leng 0
rowtar#term wid 0
rowtar#term wid 0
rowtar#
I really like the idea of trying to regex/match an expect variable to the output that matches the hostname of the device but I don't how to do that. In my example, I would try to match "rowtar#" but without per-defining that ahead of time or before the expect script is called.
The solution was looking me right in the face.
Simply:
expect -re #$
matching any line ending with #
I still encourage someone to help/answer with hostname matching to a variable

"cat" bit-stream with no EOF

I have a file opened both for reading and writing and associated this file with file descriptor 3, i.e. exec 3<>/dev/udp/10.10.10.1/161. When I redirect a crafted UDP packet to file descriptor 3 and receive a reply, then how can I read it from file-descriptor 3? Usual tools like cat or read do not work well as UDP packet(essentially just a bit stream) received as a reply does not have a newline or EOF and for example cat does not know that there is no more data to expect. For example here you can see how I had to SIGINT the cat:
$ cat <&3
0Gpublic�:�0,0+C1841.local^C
$
I would like to check if there was any UDP data received from 10.10.10.1 and this means that if file-descriptor 3 contains some data(even a single bit), then reply was received.
Your problem is that you cannot recognize an end-of-packet properly. There is not EOF (as you noticed) signifier (like a special character or file-closed event or similar). Instead all you can do is either
read a fixed size of characters (in case your packets are fixed in size) or
read single tokens (maybe bytes) until your packet's syntax states that it is complete or
read until a timeout occurred.
The first two are up to your responsibility, in case this is possible.
The last one can be achieved using a cat in a subshell which you kill after a certain amount of time:
cat <&3 & pid=$!
sleep 0.1
kill "$pid" 2>/dev/null
Put this in a function and each call will last one 0.1s and output what could be read in that time.

Recieve and reply to sms on huawei modem, gammu-smsd: Process failed with exit status 2

I Have a Huawei E220 HSDPA Modem on linux xubuntu
I wanted to recieve sms and reply automatically to the sender.
I Use gammu and Gammu-smsd to do this.
To automatically send sms back I added runOnRecieve = /path/to/bash/file into the /etc/gammu-smsdrc configuration-file.
Here is the script:
#!/bin/bash
str=$SMS_1_TEXT //string containing text from sender
tlf=$SMS_1_NUMBER //containing number from sender
tlf=${tlf:3}
if test "$str" = "today"; then
echo "[Weather for today in Norway]
Sol, noe overskyet
[Vind fra sørøst]
Ha en fin dag!" | gammu-smsd-inject TEXT $tlf -unicode -autolen 200
else
echo "fail" >> /home/mattis/sms.txt
fi
This is how I start the daemon
$ sudo gammu-smsd
This works if I run the bash script from terminal using test-input, but when the program gammu-smsd calls the script I get.
gammu-smsd[3183]: Process failed with exit status 2
Now i can remove "gammu-smsd-inject" from the code and replace with "gammu sendsms" , but that would just give me gibberish letters instead of "æøå and [ ]" when received back to the mobile.
Hoping for positive answers.
--//--Working code--//--
The thing is: Gammu sms inject acctually sends data to mysql database called smsd.
Creating this database:
This should be created as specified in wammu sql database. Storing the SQL script for creating tables in MySQL database will able you to import it with phpmyadmin(gui) or any other way to interface mysql.
Run on recieve
Add to the end of /etc/gammu-smsdrc --configuration file for gammu
runOnRecieve = /path/to/bash/file
Open the /path/to/bash/file
#!/bin/bash
str=$SMS_1_TEXT //codeword "weather"
tlf=$SMS_1_NUMBER //+47 41412424
tlf=${tlf:3} //remove +47
if test "$tlf" = "41412424"; then
toSend = "[Weather for today in Norway]"
else
toSend = "[you are not part of this group]"
echo "Someone outside the group send to this number" > /home/user/activity.txt
fi
mysql --host=localhost --user=username --password=pw smsd << EOF
INSERT INTO outbox (
DestinationNumber,
TextDecoded,
CreatorID,
RelativeValidity
) VALUES (
'$tlf',
'$toSend',
'Program',
'255'
);
EOF
Start the daemon
$ sudo gammu-smsd
That should be it!
Extra tips:
Use $ gammu-detect to find out where the device is connected. Look for name = Phone on USB serial port HUAWEI_Technology HUAWEI_Mobile or something similar. Put this info in the configfile.
Be shure to add right permission to the bashfile. Make it readable to user running gammu-smsd.
Make the bashfile executable using chmod u+x /path/to/bash/file.
The gammu-smsd-monitor can be used to check how good signal you have. Be shure not to stop running the gammu-smsd when trying to run this.
You can test the bashfile by running it with dummy tlf and dummytext as input. $ ./bashfile.sh.

Resources