0

I have a raspberry pi which stays on for extended period of time. To avoid it from crashing, I have a cron job that periodically checks for top memory consuming apps and then restarts them as needed. The shell script monitors the services correctly but for some reason doesn't restart lxpanel correctly. The shell script runs as sudo and uses the following to restart the lxpanel service:

sudo -u mimo lxpanelctl restart , where mimo is my username

I do not see a drop in memory usage, so it doesn't seem that the command successfully restarts lxpanel. Whereas if I run lxpanelctl restart from a terminal instance, I do see the required/expected drop in lxpanel's memory usage.

So now the question is how can I run lxpanelctl restart from within the script.

I've tried:

  • lxpanelctl restart, which when invoked from the script running as sudo, kills the desktop session and requires a relogin
  • sudo -u mimo lxpanelctl restart doesn't appear to actually restart the panel as I do not see a drop in mem usage.
  • runuser -l mimo -c 'lxpanelctl restart' doesn't appear to actually restart the panel as I do not see a drop in mem usage.

1 Answer 1

1

cron does not run in the same environment as the shell in your terminal.

Think about this for a moment before moving on... let it sink in.

Let's do an experiment:

At the shell prompt (I'll assume bash) in your terminal, check what your environment is using the following command:

$ printenv

Note particularly, in the output of this command, the value of the environment variable PATH; for example, on my system it is:

PATH=/home/pi/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

You may be tempted to assume that your cron job runs under the same environment... after all, it is your crontab. But let's try to confirm that assumption by asking cron to tell us what its environment actually is.

To do this, we'll create another cron job for that purpose: Open your crontab for editing (crontab -e - or - sudo crontab -e if you need elevated privileges for your job), and add the following line:

* * * * * printenv > /home/pi/cronenvironment.txt 2>&1

Once this has run, inspect the file /home/pi/cronenvironment.txt, and again, pay particular attention to the PATH environment variable. For example on my system:

PATH=/usr/bin:/bin

And so we see that the PATH environment variable under cron is not the same as the PATH in your bash shell.

This suggests a potential cause for your problem:

lxpanelctl is not in a directory that is in cron's PATH.

If that's the case, the best remedy is also the simplest:

sudo -u mimo /full/path/to/lxpanelctl restart

Let us know how this works, or if you have any questions.


Just as a comment: If you need elevated privileges in a cron job, it is often a better solution to use the root crontab instead of using sudo in your user pi crontab; i.e. use sudo crontab -e. You can get away with using sudo inside a user crontab in RPi OS only because this distro is default-configured with the NOPASSWD declaration for user pi. That's not typical, and is "frowned upon" by some who spend time thinking about computer security. And finally, do not invoke sudo in the root crontab.

P.S. You should now disable the cron job you added to run printenv.

3
  • Yeah running the script as sudo cron. The full path /full/path/to/lxpanelctl restart did help but now I am getting "cant connect to display: (null)" error, which I do not get running the command directly in the terminal
    – Akt
    Commented Aug 15, 2021 at 18:43
  • Thanks for helping. I was able to fix: "cant connect to display: (null)" by exporting DISPLAY=":0.0". All working as intended after that
    – Akt
    Commented Aug 15, 2021 at 19:02
  • @Akt: Yes - DISPLAY being another environment variable. Glad this helped, and please read this.
    – Seamus
    Commented Aug 15, 2021 at 19:30

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