-->

Cron scheduler of python script using notify-send

2020-07-30 10:53发布

问题:

I'm having some difficulty using these three technologies together.

Cron entry:

* * * * * /usr/bin/python /path/to/python/email/program.py

Python program:

  1 #!/usr/bin/python
  2 
  3 import imaplib
  4 import os
  5 import sys
  6 import pynotify
  7 
  8 if not pynotify.init('Emails'):
  9     sys.exit(1)
 10 
 11 with open('/path/to/python/email/count.tmp', 'r') as file:
 12     data = int(file.read().strip())
 13 client = imaplib.IMAP4_SSL('mail.sever.com', '993')
 14 client.login('user@server.com', 'password')
 15 client.select()
 16 
 17 unseen = client.search(None, 'UnSeen')[1][0].split()
 18 
 19 if unseen[0] == '':
 20     pass
 21 else:
 22     if len(unseen) != data:
 23         n = pynotify.Notification(str(len(unseen) - data) + " New Messages",
 24             str(len(unseen)) + " Unread Messages",
 25             "file:///path/to/python/email/mail.png")
 26         if not n.show():
 27             print "Fail"
 28             sys.exit(1)
 30         with open('/path/to/python/email/count.tmp', 'w') as file:
 31             file.write(str(len(unseen)))

The script works correctly when run by itself, but it will not run when scheduled as a cron job. I checked the syslog and it says the script is being run, and I've run as sudo the line from the log to verify.

I've checked

Execute python Script on Crontab

and

Cron with notify-send

but neither, nor further links seem to address this combination.

Any thoughts?

-Update 1-

As pynotify seems not to allow the program to work at all, I've replaced their calls with an os.system call. At least this updates the small tmp file, but still no notify.

os.system('/usr/bin/X11/notify-send "{} New Messages" "{} Unread Messages"'.format(len(unseen) - data, len(unseen))

-Update 2-

/usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:57: GtkWarning: could not open display
warnings.warn(str(e), _gtk.Warning)

** (other.py:16509): WARNING **: Command line `dbus-launch --autolaunch=91bdcc4a583bfb56734fbe1200000010 --binary-syntax --close-stderr' exited with non-zero exit status 1: Autolaunch error: X11 initialization failed.\n

回答1:

When you run your program manually, it works because the variable DISPLAY is being set to your current display (:0 in most cases), however when running the script via cron, there is no such variable being set and notifications doesn't work.

As mentionned in this answer, you should export both the display and the Xauthority, and finally running the script as your user (and not as root).

Try something like this :

* * * * * export DISPLAY=:0.0 && export XAUTHORITY=/home/<username>/.Xauthority && sudo -u <username> /usr/bin/python /path/to/python/email/program.py

(change <username> with your username)



回答2:

Change your cron entry to * * * * * /usr/bin/python /path/to/python/email/program.py >> /var/log/program.log 2>&1 and see what you get in log file program.log You can add print statements to your program to debug better (as you will get them in program.log)



回答3:

Try this command:

*\1 * * * * sudo -u user DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus notify-send 'Hi.'


标签: python cron