0

I have found similar threads regarding this issue and it's always solved by specifying full paths everywhere. I have done that, but it still doesn't work.

I have written a python script which checks the battery charging status of my laptop. I want this to check every minute and notify me if the status is not 'idle'. I've added an extra bit which logs when the script has run; that bit is only to help debug the issue I have with crontab not running the script.

My script is this:

#!/usr/bin/python3

import os from datetime import datetime

date_time = datetime.now().strftime("%d/%m/%Y, %H:%M:%S")

output = os.popen('sudo /usr/bin/tlp-stat -s -c -b | /usr/bin/grep "BAT0/status"').read().split('=')[1].strip()

if not output == 'Idle': os.system('/usr/bin/notify-send -u critical "Battery not on idle"')

with open('/home/admin/batteryLog.txt','a') as f: f.write(output + ": " + date_time+"\n")

I added this script to crontab using crontab -e and it looks like this: * * * * * /usr/bin/python3 /home/admin/checkBattery.py

People here have suggested using env -i /bin/bash --noprofile --norc to get the bash environment that the crontab uses. My script runs fine here so I don't know what could be causing it to not run in crontab.

I have run chmod a+x on the python script, I added the shebang #!/usr/bin/python3 just in case it helped. I included full paths everywhere I could, but I don't think the issue is paths because it runs fine in the noprofile environment.

I also read that people suggest using cd in crontab to change directory to the location of the python script, but my script is in the root directory so it can't be useful to do that.

I've run which python3 and it returns /usr/bin/python3 so I'm definitely in the right place there too.

Does anyone know anything else I can try here?

  • "specifying full paths everywhere" Oh? tlp-stat? notify-send? – Rinzwind May 07 '21 at 23:31
  • @Rinzwind No, I already tried with them too, but I left them out in the version I posted. I edited it now. – Alfie Stoppani May 07 '21 at 23:42
  • I did actually forget Grep, but I added the path to that now and tried it. It's still not working. – Alfie Stoppani May 07 '21 at 23:47
  • Dies the script run without errors when you run it in the terminal ? If it dues, try redirecting output and errors of script in cron, by adding > logfile 2>&1 to the end of the line in crontab. 'logfile' will be created i the users home-dir, use full path if you want it elsewhere. Look at the content of logfile to see what fails. – Soren A May 07 '21 at 23:59
  • 1
    I see a couple of potential issues: (1) notify-send needs to communicate with the user's display - see How to use notify-send with crontab? and (2) sudo likely wants a TTY in order to prompt the user for their password – steeldriver May 08 '21 at 00:51
  • If you are running roots crontab you don’t need any sudo commands. It’s possible to waste hours on cron, systemd timers are avoid most of the typical cron issues once you can set up the unit file, which is not very difficult. – PonJar May 08 '21 at 09:27

1 Answers1

1

So this has taken me all week to fix. But I have it now. Here's what I did.

There were two separate issues. As @steeldriver said, notify-send doesn't work from crontab without specifying details with the display. I changed that line to export XDG_RUNTIME_DIR=/run/user/1000; /usr/bin/notify-send -u critical "Battery Not on Idle" ""

The other problem was with /usr/bin/tlp-stat -s -c -b. I couldn't get the permissions right for it to run in crontab somehow. It did however run in crontab as root accessed by sudo crontab -e. But... having this as root caused the notify-send to stop working. I spent days and days fiddling, but I ended up having to write two bash scripts, one in sudo crontab -e to get the battery status and output using echo to a text file; and another cronjob in crontab -e to read the output file and display the message if the status wasn't idle.