3

I have a Raspberry Pi connected to a VPN via openvpn. Periodically, the connection drops, so I use the following script:

#!/bin/bash
ps -ef | grep -v grep | grep openvpn
if [ $? -eq 1 ] ; then
        /sbin/shutdown -r now
fi

I added it to crontab (using sudo crontab -e), I want the script to be executed every 5 minutes:

*/5 * * * * /etc/openvpn/check.sh

The script doesn't work, but it still seems to be executed every five minutes:

tail /var/log/syslog | grep CRON

gives:

Mar 16 21:15:01 raspberrypi CRON[11113]: (root) CMD (/etc/openvpn/check.sh)
...

Moreover, when I run the script manually with sudo ./check.sh, the Pi reboots just like it should.

I don't really understand what's going on here ?

Edit :

As suggested, I added the full path names and went from rebooting the Pi to restarting openvpn:

#!/bin/bash
if ! /bin/ps -ef | /bin/grep '[o]penvpn'; then
        cd /etc/openvpn/
        /usr/sbin/openvpn --config /etc/openvpn/config.ovpn
fi

The script still doesn't work, although it runs fine when I execute it myself. The script's permissions are 755, so it should be ok ?

Brummbaer
  • 31
  • 4
  • Consider using `killall -0 openvpn`. If the process exists you'll have $? equals to zero. Perhaps it's permission problem so the user who's crontab you edit isn't allowed to perform shutdown operation. Try to put `bash -x /etc/openvpn/check.sh 2>&1 | logger -t OPENVPNCHECK` into crontab. – frist Mar 16 '18 at 21:24
  • 1
    You might need to set the path in your check.sh, since cron doesn't run with the user PATH, or use absolute paths. – user unknown Mar 16 '18 at 21:36
  • @frist I used `sudo crontab -e` (sorry, should have clarified in the question), so I don't think there should be any permission problem ? – Brummbaer Mar 16 '18 at 22:06
  • 3
    why restart?! can't just reconnect vpn? – LMC Mar 16 '18 at 23:07
  • Did you set the permissions on check.sh to something like 750? –  Mar 17 '18 at 00:36
  • 1
    In the script, add the full paths to the binaries, so /bin/ps, etc. (obtain them with a command like 'which grep', etc.). –  Mar 17 '18 at 00:44
  • @Roadowl that's a reasonable debugging technique, but the final script should just make sure it runs with a sane `PATH`, and not hard-code command paths. (And use `type`, not `which`.) – tripleee Mar 17 '18 at 08:28
  • @LuisMuñoz I'll try using the `keepalive`setting when starting openvpn first, and I'll modify the script to include binary paths. Thanks – Brummbaer Mar 17 '18 at 09:11

2 Answers2

3

The path name of the script matches the final grep so it finds itself, and is satisfied.

The reason this didn't happen interactively was that you didn't run it with a full path.

This is (a twist on) a very common FAQ.

Tangentially, your script contains two very common antipatterns. You are reinventing pidof poorly, and you are examining $? explicitly. Unless you specifically require the exit code to be 1, you should simply be doing

if ! ps -ef | grep -q '[o]penvpn'; then

because the purpose of if is to run a command and examine its exit code; and notice also the trick to use a regex which doesn't match itself. But using pidof also lets you easily examine just the binary executable's file name, not its path.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Rebooting when a process dies also seems excessively brutal. Is there a reason you don't simply restart it? – tripleee Mar 17 '18 at 08:22
  • actually, there's no real reason, I just thought it'd be easier this way. Thanks, I will change my script when I get home – Brummbaer Mar 17 '18 at 09:05
0

I finally understood why the script didn't work. Since it was located under /etc/openvpn, the condition if ! ps -ef | grep -q '[o]penvpn' wouldn't return true because of the script being executed. I noticed it when I changed the crontab line to:

*/5 * * * * /etc/openvpn/check.sh >/home/pi/output 2>/home/pi/erroutput

the output file showed the /etc/openvpn/check.sh script being run.


The script now is:

#!/bin/bash
if ! pidof openvpn; then
        cd /etc/openvpn/
        /usr/sbin/openvpn --config /etc/openvpn/config.ovpn
fi

and this works just fine. Thank you all.

Brummbaer
  • 31
  • 4