Send display to user from a root job - python

I have a job that starts in crontab with root privilege. This job should display a popup message after a while. The job is in python and use MessageBox toolkit.
With roit, the job works and after 5 minutes, I see the messagebox.
The problem is that if I login as a user, I can see the job running in the tasks list but the popup does not work (probably since the display of the job is of the root and not the user).
I cant find the way to change this job to use the display of the current ligin user.
Is there a way to change this so the user will see the popup?
Thanks.

The MessageBox does not popup because the cron job run in an environment where the DISPLAY (environment variable) is not set. Instead of having cron run your python directly, you can make it run a simple wrapper around it:
#!/usr/bin/env bash
export DISPLAY=':0'
python /path/to/your/python/program.sh
Alternatively, if your confident it won't mess with other cron jobs, you can add DISPLAY=:0 as the first line of your crontab.

Related

Python logger not logging when called with scheduler on windows server 2012

I wrote a simple "git pull" script to be run on a Windows Server:
import logging
import subprocess
# Initialize logging
logger = logging.getLogger('autopull')
logger.setLevel(logging.INFO)
log_file = logging.FileHandler('autopull.log')
log_file.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s:%(levelname)s:%(message)s")
log_file.setFormatter(formatter)
logger.addHandler(log_file)
# Main part
logger.info('Started')
try:
subprocess.check_output("C:\Program Files\Git\cmd\git pull")
logger.info('Pulled repo successfully')
except:
logger.exception("Pulled failed")
I used a logger because the scheduler always told me that it executes with exit code 0 and I wanted to double check whether it was the case.
When I call the script by hand, it is working fine and the logger writes in the autopull.log. However, when it is called by the scheduler, the logger writes nothing. The task runs with the "Run with highest privileges" and "Run whether user is logged or not".
Is there something I did wrong ?
Edit 1 : Added Scheduled Task parameters
General :
"Run whether user is logged on or not" and "Run with highest privileges".
Configure for : Windows Server 2012 R2
Triggers:
Trigger : One time
Details : At 12:30 PM on 6/26/2017 - After triggered, repeat every 1 hour indefinitely
Status : Enabled
Actions:
Action : Start a program
Details : D:\Anaconda3\python.exe D:\projects\foo\autopull.py
Conditions:
"Start the task only if the computer is on AC power" and "Stop if the computer switched to battery power".
Settings:
"Allow task to be run on demand" and "if the running task does not end when requested, force it to stop".
#Dr Mouse, try this. I was able to run your code (while logged off). FYI, I am running Anaconda on Windows as well.
Once in the Edit Action window (in your actions, that you showed above, click on the edit button), in the program/script, be sure that it is pointing to the actual instance of your Python (Anaconda).
Put double quotes around the Program/Script
"D:\Anaconda3\python.exe"
Do not copy and paste, type it in.
In the add arguments optional:
-u "D:\projects\foo\autopull.py"
In Start in (optional) add the folder location to the script without quotes:
D:\projects\foo
If the above doesn't work, for troubleshooting purposes:
Does it work when you click on run (which runs it immediately) in task scheduler (naturally while logged in)?
In task scheduler, did you look through the history of the task to see where the scheduler is failing?
EDIT: Thinking more about it, I remember there was some issue with running python directly using the "Run whether user is logged on or not".
If the above does not work, try this:
create batch file (.bat) and add this line in it:
D:\Anaconda3\python.exe D:\projects\foo\autopull.py %*
point the task scheduler to this batch file (instead of pointing it to the python script directly).

How to schedule a script to run at a specified time only on weekdays on Windows 10?

I have tried to run a Python script via the Windows 10 task scheduler but the script will not run:
I have double-checked the path to python and to the script. What could be the problem with the task scheduler? Is there any other ways to schedule the script? I need it to run five days a week at a specified time through the day, every week.
You might be able to get additional relevant information from the events log. Open Event Viewer (right-click on Start). In the left panel select 'Applications and Service Log', then 'Microsoft', then 'Windows', then 'TaskScheduler', the 'Operational'. You might find that the associated middle panel is empty because this log is disabled. In this case, right-click on 'Operational' and enable it temporarily.
Now go to Task Scheduler. Select your task, then click on 'Run' from the right panel a few times, and return to Event Viewer. I hope you will see something useful in the bottom window like
Task Scheduler failed to start "\Play a video" task for user "DESKTOP-K76A078\Bill". Additional Data: Error Value: 2147942402.
Presumably the number won't be the same for you. However, you can google for error value nnnnnnnnnn and get various speculations about mistakes or error conditions that you could look for.
Best of luck!
In Windows 10, if you install the Windows 10 Anniversary Update, you'd be able to install the Linux on Windows subsystem. Then, just use cron (crontab) to define any recurring task.

Zenity not working in python script with crontab

I have a python script in which I have used Zenity to display some notification. The code snippet is as follows:
if message_list:
pretty_print(message_list)
os.system("/usr/bin/zenity --notification --text='You have unread messages'")
When I run this script normally, everything works fine i.e. dialog box appears and message gets displayed. But when I schedule this script in crontab nothing appears. Any solution to this?
There is no sane way to run interactive commands from cron. There is no guarantee that there is a user, there is no guarantee that there is a single user, there is no guarantee that the user(s) who are on want to, or are even able to, interact with your software; some of them may be pseudo-users or remote on expensive metered Internet access or just idle or whatever.
The usual solution is a server/client architecture where whatever runs from cron makes its results available via some IPC mechanism, and users who want the results run a client from within their X11 session (or shell, or what have you).
Create a script info.sh (remember to grant it execute rights):
#!/bin/bash
xhost +
/usr/bin/zenity --notification --text='You have unread messages'
And in your script:
if message_list:
pretty_print(message_list)
os.system("./info.sh")
That's if you want to use the solution you mentioned.

Restart Python with threading or crontab

I have written a function that crawls and clusters news articles. I want this function to restart every 10 minutes, aiming to get the newest articles. I wrote a Python script that this with the help of threading module:
import threading
def run():
do_it()
if not END:
threading.Timer(600.0, run).start()
END = False
threading.Timer(600.0, do_it).start()
It works fine with Python IDLE. Now I see in different forums that "crontab" is mentioned for this purpose. Since I plan to host this application on the web and since I have no prior experience with web development/hosting, what would you suggest to me: to continue with the previous code or to try to do it with the "crontab" function? I am working with the Django framework.
Using Django doesn't really work in this context. if you want to use a cron script then you will want it running independently of your webserver (you don't want your webserver ending after you finish the script). Alternatively you could start up a GET or POST request to an already running Django instance by this method.
First type crontab -e at a prompt in your unix based os or mac. (since you mentioned crontab I'll assume your not using windows)
This will allow you to edit a file for the user you are logged in as. This is the line you will want to type to get a do_it.py file to run every ten min.
*/10 * * * * do_it.py
For more information at your prompt type man 5 crontab. Other modifications you could make are prefixing the word sudo to the command which would allow you to change root's crontab.

How do I know if jobs have been/are performing? - Crontab

I have followed the suggestion in this question
as I am using Django, I have set the script to store date and time of each run of the script in the db, but no entry has been stored yet in the database.
Is there a way to figure out, other than typing "top" and searching through?
First, I would probably configure cron to mail yourself any output by using MAILTO:
In /etc/crontab:
MAILTO=username
Second, I usually add something to my script that (almost) cannot possibly fail, like the following:
#!/bin/sh
echo "$0 ran on `date +%c`" >> /tmp/crontab_test.log
# ... rest of program
If you're calling a python script directly from cron, you could do something similar or create a wrapper shell script.
If you have sendmail installed, you can add the following to '/etc/aliases'
root: your_name#domain.com
After you do that, update the aliases running this command:
sudo newaliases
Cron will automatically email you every time a job is run. No need to specify that in the crontab file.
Also, make sure you test your email capabilities (e.g. make sure you are able to send emails from the server) and lastly, create a trivial cronjob and test if you receive an email.
Do not assume!
In addition to setting up cron to send email, you can send the output of cron to a seperate syslog log facility by adding the following to your /etc/syslog.conf.
# Log cron stuff
cron.* /var/log/cron.log
This should log a message to /var/log/cron.log each time a job is run.

Categories

Resources