expect script failing at last prompt - expect

I'm writing a script to update firmware on multiple terminal servers. So far the script works perfect up until the last step, where I'm asked whether I'd like to reboot (yes, no)...
The CLI commands for the terminal:
--:#- [system_tools] cli-> download
--:#- [system_tools] cli-> install
Jun 12 23:49:19 xx.xx.com event_notify: EVT[11]:Image upgrade started. User: root. Current version: 2.5.0.12. New version: 3.1.0.13.
finish
Jun 12 23:51:34 xx.xx.com event_notify: EVT[12]:Image upgrade result. Result: 0. New firmware version: 3.1.0.13.
--:#- [system_tools] cli-> finish
--:- / cli-> reboot
Rebooting the appliance will cause all currently active sessions to be disconnected.
Are you sure you want to reboot the appliance? (yes, no) :
These are the last few lines of the expect script:
send "finish\r"
expect "$"
send "reboot\r"
expect "Rebooting the appliance will cause all currently active sessions to be disconnected.Are you sure you want to reboot the appliance? (yes, no) : "
send "yes\r"
However the yes does not get sent. The script ends at:
Are you sure you want to reboot the appliance? (yes, no) :
and doesn't go any further. What am I missing here? Why isn't the "yes\r" sent?
Thanks

Looks like there's a newline "disconnected." and "Are you sure". You might want to just do this:
expect "Are you sure you want to reboot the appliance? (yes, no) : "
As to why it waits forever, did you change the timeout variable in your script?
Pro-tip: debug your expect script with expect -d script.exp

Related

Is there a way to get my laptop to beep from within a bash script running on a remote server via SSH?

I have a bash script that I have to regularly run on a remote server. Part of the script includes running a backup which takes a while, and after it has run, I have to hit "Y" to confirm that the backup worked before the script will continue.
I would like to know if there is a way to get my laptop to make a beep (or some sort of sound) when that happens. I know that echo -e '\a' makes a beep, but if I run it from within a script on the remote server, the beep happens on the remote server.
I have control of the script that is being run, so I could easily change it to do something special.
You could send the command through ssh back to your computer like:
ssh user#host "echo -e '\a'"
Just make sure you have ssh key authentication from your server to your computer so the command can run smoothly
In my case the offered solutions with echo didn't work. I'm using a macbook and connect to an ubuntu system. I keep the terminal open and I'd like to be informed when a long running bash script is ready.
What I did notice is that if I shutdown the remote system then it will beep the macbook and show an alarm icon on the relevant tab. So I have now implemented a bit of dirty workaround:
sudo shutdown 1440 && shutdown -c
This will initiate the system to shutdown and will immediately cancel the request. And I do get the alarm beep + icon. You will need to setup sudo to allow the user to permit shutdown. As it was my own remote server it was no problem but could limit the usability for others.

Why can not I use expect script to start redis?

I guess there must be a simple reason why I can't start redis like this
---- update -----
After #larsks answered my question I realize it is this one that cause my confusion "You end it with an interact statement, which conncets your console to the stdin/stdout of the process you spawned. The redis-server program is not interactive: it doesn't accept any console input."
I check the code again and found it was this code that made me think the process was stuck
#!/usr/bin/expect -f
spawn redis-server
expect "The server is now ready to accept connections"
interact
spawn redis-cli
expect ">"
...
I never saw redis-cli run.
But if I change to
#!/usr/bin/expect -f
spawn redis-server
expect "The server is now ready to accept connections"
spawn redis-cli
expect ">"
...
interact //put it in the end.
It works as I expected.
BTW the reason I use expect here is first to make sure redis server starts then delete some keys.
What do you expect the first example to do? You end it with an interact statement, which connets your console to the stdin/stdout of the process you spawned. The redis-server program is not interactive: it doesn't accept any console input. When you run redis-server, it will get as far as...
1135:M 18 Nov 13:59:51.634 * Ready to accept connections
...and then it stops, waiting for redis clients to connect and operate on it. Also, note that the Redis version I'm using ends with Ready to accept connections rather than The server is now ready to accept connections, so I'll be using that in the following examples.
We can add a puts command to the expect script to see that it isn't
actually getting stuck anywhere. If I run the following:
#!/usr/bin/expect -f
spawn redis-server
expect "Ready to accept connections"
puts "redis is running"
interact
I get as output:
spawn redis-server
1282:C 18 Nov 14:03:33.123 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1282:C 18 Nov 14:03:33.123 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=1282, just started
[...]
1282:M 18 Nov 14:03:33.124 * Ready to accept connections
redis is running
So we can see that it's not getting stuck at the spawn statement,
nor even at the expect statement.
What's not clear from your question is why you're even using expect
in this situation, since redis-server is not an interactive program
and does not produce any prompts that require automation.

bash ignores & for last command in loop

I just wrote my first bash script to start some redis instances on a development server. While it is mostly working, the last opened redis instance is blocking the active terminal – though I have the trailing & sign and the other started instances aren't blocking the terminal. How would I push them all to the background?
Here's the script:
#!/bin/bash
REDIS=(6379 6380 6381 6382 6383 6390 6391 6392 6393)
for i in "${REDIS[#]}"
do
:
redis-server --port $i &
done
It sounds like your terminal is not actually blocked, your prompt just got overwritten. It's a purely cosmetic issue. Due to the way terminals work, bash doesn't know to redraw it so it looks like the command is in the foreground.
Run the script again, and blindly type lsEnter. You'll probably see that the shell responds as normal, even though you can't see the prompt.
You can alternatively just hit Enter to get bash to redraw the prompt.

Gammu: run on receive exit status 1

I'm trying to use gammu and gammu-smsd to send and receive sms with my raspberry pi using a Huawei intrnet key.
My problem is that when I send an sms from my phone to raspberry pi, it read the sms, it try to start the program linked at RunOnReceive = in /etc/gammu-smsdrcn file but then, it says: Process failed with exit status 1.
I tried any kind of solution but I'm not capable to solve this problem by my self; I've set each permission on the script.
Can someone help me?
Thank you a lot.
You no doubt have this sorted by now, but I have just been through the same trip, tore out a lot of hair and finally made it out the back .... :-)
I'm using a ZTE stick with wvdial for internet connection. The stick appears as modems on /dev/USBtty0, 1 and 2. wvdial uses USBtty2, so gammu (I think) has to use a different one.
So I installed gammu/gammu-smsd on USBtty1 in gammu-config and /etc/gammu-smsdrc. The receive daemon gammu-smsd fires up automatically on boot.
First trap for young players - if you want to send an SMS with
echo "whatever" | gammu sendsms TEXT xxxyyyzzzz (where the last is the phone no) - you need to kill the receive daemon for that to work ie
service gammu-smsd stop # kill receive daemon
echo etc etc gammu etc etc # send the SMS
service gammu-smsd start # revive the receive daemon
Now for the RunOnReceive thing ...
start with sudovi - gives some config file to edit. There's a line in there about pi BLAH-BLAH-BLAH as a sudoer. Duplicate it with gammu BLAH-BLAH-BLAH. Same BLAHs. Save it.
It's something to do with permissions - I'm not an expert here :-)
So my RunOnReceive line is { sudo /home/pi/procSMS.sh $SMS_1_TEXT }
The script didn't seem to know what $SMS_1_TEXT was, so I passed it through as a parameter - inside the script it's treated as $1. It works.
While testing I ran a process in another window - just tail -f /var/log/syslog which lets you watch it all in real time ...
I was getting the same error on Raspberry Pi in combination with Huawei E3131 (Process failed with exit status 1) but I solved it.
make sure you have file permissions set well. Gammu runs deamon under "gammu" user by default. So you can change it (/etc/init.d/gammu-smsd) to user who is already located in your system and has rights for executing the script. Or change script permissions by following: chmod 755 script.sh. It means you give execute rights to other users too.
In fact there is additional option. Run gammu deamon with parameter -U username. Unfortunatelly it did not work for me when I used root user.
PS: I would recommend to not to place the script inside /etc directory. Use /home directory instead.
turn on debuging in /etc/gammu-smsdrc. Use parameters: logformat and debuglevel in section smsd. Default log is located in /var/log/syslog. May be it helps you deeply localize the problem.
And the best at the end... I found that gammu returns the error even if it runs the script well! You have to write exit code inside you bash script. If you do not specify an exit code, gammu represents it as error 1. Add exit 0 in case of success in the end of the script and error message disappears.

In bash, how do I reestablish sftp connection and run it in a script that makes nautilus do it?

I have a bash script that tests whether the sftp connection exists, very simple one:
$ if [ -d ~/.gvfs/sftp for username on 192.168.1.101 ]; then echo "sftp missing" exit; fi
Now heres the question:
How do I make the script reestablish the previously connected sftp that still has a cached pass to reconnect without having it depend on if the bash script is on?
Since I have a bookmarked sftp thing in nautilus, i just point and click, presto its reconnected. I need the same for my script which will TERMINATE in a couple of lines; in other words the script only reconnects nautilus and dies, connection stays open...
I am still noobish at sftp, besides connecting...
Extra info: I use Ubuntu for both client and server, and i dont mind entering the ssh pass again if its new conection, any help is appreciated :D
Its critical that sftp wont d/c, or die, when i close script, or it ends, nohup cant be used for script since it will be run >10 times per day
Thanks!
Okay, some research done. You are using the GVFS (GNOME Virtual File System), and are looking with a none-GNOME application (bash) on the FUSE mount point of one of the URIs.
I think you can use the gvfs-mount command to reconnect, if you know the SFTP URL, but I didn't really find much documentation about this.

Resources