1

I have a bash script that runs every hour. Output of this is sent to me via email. This is run through cronjob.

#!/bin/bash
# Script: temp_email.sh
# -------------------------------------------------------

cpu=$(</sys/class/thermal/thermal_zone0/temp)
echo "$(date) @ $(hostname)"
echo "-------------------------------------------"
echo "GPU => $(/opt/vc/bin/vcgencmd measure_temp)"
echo "CPU => $((cpu/1000))'C"
echo "-------------------------------------------"
echo ""
echo ""

As of now it provides temperatures via email. I wanted to add a loop and self-healing to mounted drives and http service.

I am using following commands to get results of apache2 service status

systemctl list-units --no-legend apache2.service | cut -d' ' -f4

The output if the service is running is "running". I want the loop to attempt to start the service if the status is anything but running. Output of this attempt.

I use the following to check status of external drives mounted to the Raspberry Pi.

 lsblk -dlno NAME,MOUNTPOINT /dev/sd??*

Again, I want to put this in a loop wheirein if the drive is unmounted it will first gracefully stop the apache2 service, mount the drive and later start the apache2 service.

I am unable to get "if & then statements" correctly. I do not want any changes in case both the service and drives are running as they should.

Thank you.

3 Answers 3

2

As I don't know how the output from systemctl command should be, I just will give you the steps I would follow:

  • Don't use a loop. Use cron to execute your script periodically.
  • Process the output of systemctl with grep for searching for a pattern of interest indicating mount status, and store this response.
  • Process your response using an if to execute lsblk if needed

It would be something like this:

# script.sh
apache_running=1
systemctl status apache2.service | grep "running" || apache_running=0

if [ $apache_running -eq 0 ]
then
  echo "Apache is not running"
  lsblk -dlno NAME,MOUNTPOINT /dev/sd??*
else
  echo "Apache is running"
fi

Then, you add your script.sh file as an entry to the crontab

4
  • Thank you and just a quick response that I do use cronjob for the script. Thank you. Nov 14, 2018 at 12:46
  • I am not sure how will work. I see only one If statement and there should be two (according to me) -- One for apache status and one for the mounted drives both having their actions. Nov 14, 2018 at 12:48
  • In that case, you will have to check 2 conditions (with an AND operator), one for apache status and another for device status. If you have a list of devices to check, you can iterate through them in a for, I guess. It would be helpful If you provide an example output for each case. Nov 14, 2018 at 13:01
  • I updated the answer for Apache service checking. But, what is the output of lsblk and how you identify the device to re-mount? Nov 14, 2018 at 14:34
2

Instead of parsing the output of systemctl list-units, use systemctl is-active, and you can do things like this:

#!/bin/sh
# Mount point names in systemd unit style, with initial slash omitted and the
# rest replaced by dashes:
MOUNTPOINTS="MOUNT-POINT1 MOUNT-POINT2"

FAILED=0
for mountpoint in $MOUNTPOINTS
do
    if ! systemctl -q is-active $mountpoint.mount
    then
        echo "$mountpoint.mount is not active."
        if systemctl -q is-active apache2.service
        then
            echo "Stopping Apache first..."
            systemctl stop apache2.service
        fi
        echo "Trying to fix $mountpoint.mount..."
        systemctl start $mountpoint.mount || FAILED=1
    fi
done

if [ $FAILED -ne 0 ]
then
    echo "A mountpoint was down and we failed to fix it. Panic!" >&2
    exit 69 # EX_UNAVAILABLE
fi

if ! systemctl -q is-active apache2.service
then
    echo "apache2 service is not active. Attempting to start."
    systemctl start apache2.service
fi
1
  • Thank you very much for the answer. Could you please try and help with the output of Apache2 at the end? As in, is there a way to find out if the apache restart worked or not? Nov 14, 2018 at 16:47
0

An alternative to trying to do this yourself in a shell script might be to install and configure Monit to do it for you: https://mmonit.com/monit/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.