I have a Python script, say test.py which interacts with the user everytime it is executed.
test.py
#!/usr/bin/env python3
def foo():
a = input()
print("Hello, {}".format(a))
if __name__ == '__main__':
foo()
I want to run this script every 5 minutes. So, I tried adding it to my crontab but it seems that this doesn't work as I am not prompted to enter an input.
I have tested my crontab and it is working fine.
Should I use libraries such as schedule for this task?
What would be the ideal way of going about in this scenario?
NOTE: I want a cross platform solution which works on MacOSX and GNU/Linux.
Your could try the python module pexpect (http://pexpect.sourceforge.net/doc/) -- the usage is something like :
import pexpect
child = pexpect.spawn(script/python file etc...)
child.expect('Here goes the prompt you would expect')
child.sendline('What you want to send to it')
its not possible to have cron interact interactively on your server.
Delink your application:
Setup a db (like MySQL), have test.py run via cron every 5 mins to check if a new entry is made in the db: then, have a local application that saves user prompt information to your db.
If it is running via cron or schedule, it will not be running on your terminal, it will run as a background process. Therefore, it cannot be interactive and you will not be prompted.
If you just want to put a delay of 5 minutes, have you looked at the Linux "sleep" command or using python's "time.sleep"? In this way you can keep a terminal open and just have the job run in intervals.
To keep it simple:
#!/usr/bin/env python3
import time
def foo():
a = input()
print("Hello, {}".format(a))
if __name__ == '__main__':
while True:
foo()
time.sleep(300) # Sleeps 300 seconds
You can get a script and use that in the crontab:
#!/bin/bash
/usr/bin/python3 /home/user/project/test.py << EOF
some input here
EOF
Your crontab will look like
* * * * * /home/user/project/test.sh >> /home/user/project/LOG 2>&1
Related
('The First script' takes input from the user and 'the second script' notify the task.)
I have been trying to restart a python script using another one but i couldn't succeed it after trying to do a few methods. I developed a reminder, notify user when time previously set by the user has arrived, app works on Linux and it have 2 python script. First one is for taking input that given by the user to schedule a task. For example, "Call the boss at 12:30 pm". Then Linux is going to notify it at 12:30 pm. The other one is checking the inputs and notify them when the time comes.
In first script, i am trying to restart the other script when the user give a new task because the script needs to read the new task to notify it. Also I want to terminate the first script when it ran the second script. But the second script must still be working. In first script, I tried these commands to do that:
os.system(f"pkill -f {path2}")
os.system(f"python {path2}")
These aren't work.
Also I want to run the second script at the startup of my os.
Summary:
1- I wanna restart a python script using another one and the first one should be terminated when the second one is run.
2- I wanna run the second script at the startup of my os.
Repository about my reminder app is here.
About 1 :
Assuming the name of the other script is 2.py (Changeable with the code below), this worked for me pretty well:
1.py:
import subprocess
import os
import time
OTHER_SCRIPT_NAME = "2.py"
process_outputs = subprocess.getoutput("ps aux | grep " + OTHER_SCRIPT_NAME) # Searching for the process running 2.py
wanted_process_info = process_outputs.split("\n")[0] # Getting the first line only
splitted_process_info = wanted_process_info.split(" ") # Splitting the string
splitted_process_info = [x for x in splitted_process_info if x != ''] # Removing empty items
pid = splitted_process_info[1] # PID is the secend item in the ps output
os.system("kill -9 " + str (pid)) # Killing the other process
exit()
time.sleep(1000) # Will not be called because exit() was called before
2.py:
import time
time.sleep(100)
About 2:
In linux, you can execute scripts on startup by writing it into the /etc/rc.local file
Just run your scripts from the rc.local file and you are good to go:
/etc/rc.local:
python '/path/to/your/scripts'
I have a python script, runned by cron:
"*/5 * * * * python /home/alex/scripts/checker > /dev/null &";
It has several purposes, one of them is to check certain programs in ps list and run them if they are not there. The problem is that script when runned by cron not executed programs in backgroung correctly, all of them are in ps list look like:
/usr/bin/python /home/alex/exec/runnable
So they look like python scripts. When I launch my python script manually it seems that it executes runnable in background corretcly, but with cron nothing works.
Here's the example of code:
def exec(file):
file = os.path.abspath(file)
os.system("chmod +x " + file)
cmd = file
#os.system(cmd)
#subprocess.Popen([cmd])
subprocess.call([cmd])
I tried different approaches but nothing seems to work right.
Some code update:
pids = get_pids(program)
if pids == None:
exec(program)
print 'Restarted'
I am developing some Python (version 3.6.1) code to install an application in Windows 7. The code used is this:
winCMD = r'"C:\PowerBuild\setup.exe" /v"/qr /l C:\PowerBuild\TUmsi.log"'
output = subprocess.check_call(winCMD, shell = True)
The application is installed successfully. The problem is that it always requires a reboot after it is finished (a popup with a message "You must restart your system for the configuration changes made to to take effect. Click Yes to restart now or No if you plan to restart later.).
I tried to insert parameter "/forcerestart" (source here) in the installation command but it still stops to request the reboot:
def installApp():
winCMD = r'"C:\PowerBuild\setup.exe" /v"/qr /forcerestart /l C:\PowerBuild\TUmsi.log"'
output = subprocess.check_call(winCMD, shell = True)
Another attempt was to create a following command like this one below, although since the previous command is not finished yet (as per my understanding) I realized it will never be called:
rebootSystem = 'shutdown -t 0 /r /f'
subprocess.Popen(rebootSystem, stdout=subprocess.PIPE, shell=True)
Does anyone had such an issue and could solve it?
As an ugly workaround, if you're not time-critical but you want to emphasise the "automatic" aspect, why not
run the installCMD in a thread
wait sufficiently long to be sure that the command has completed
perform the shutdown
like this:
import threading,time
def installApp():
winCMD = r'"C:\PowerBuild\setup.exe" /v"/qr /l C:\PowerBuild\TUmsi.log"'
output = subprocess.check_call(winCMD, shell = True)
t = threading.Thread(target=installApp)
t.start()
time.sleep(1800) # half-hour should be enough
rebootSystem = 'shutdown -t 0 /r /f'
subprocess.Popen(rebootSystem, stdout=subprocess.PIPE, shell=True)
Another (safer) way would be to find out which file is created last in the installation, and monitor for its existence in a loop like this:
while not os.path.isfile("somefile"):
time.sleep(60)
time.sleep(60) # another minute for safety
# perform the reboot
To be clean, you'd have to use subprocess.Popen for the installation process, export it as global and call terminate() on it in the main process, but since you're calling a shutdown that's not necessary.
(to be clean, we wouldn't have to do that hack in the first place)
I have multiple python files to run. How would I launch all those files within one .py script? This is what I came up with but it shows the screen action and really doesn't begin the other stuff unless I exit out of it. Here's the code, not much:
import os
print("Launching Bot, just for you.")
print("Loading up shard 0")
try:
os.system("screen python3.5 run_0.py > /dev/null")
except:
print("Shard 0 failed")
print("Loading up shard 1")
try:
os.system("screen python3.5 run_1.py > /dev/null")
except:
print("Shard 1 failed")
print("Done running shards...")
I was doing some research and they said to use subprocess but when I used it, it didn't run my command properly. (I don't have a copy of that code, I lost it).
The problem is that I want to run the python script and it works fine but I have to close the screen to start the other one and I just want it to run the command w/o showing the output. Can you help?
You should use import subprocess in a python file. You can then start other instance of other programs with :
subprocess.Popen([sys.executable, "newprogram.py"])
You can mix that with multiprocessing package to launch one thread by new program
p = multiprocessing.Process(target= mp_worker , args=( ))
p.start()
where mp_worker launches the other program.
I have a script that collects data from the streaming API. I'm getting an error at random that I believe it's coming from twitter's end for whatever reason. It doesn't happen at specific time, I've been seen it as early as 10 minutes after running my script, and other times after 2 hours.
My question is how do I create another script (outside the running one) that can catch if it terminated with an error, then restart after a delay.
I did some searching and most were related to using bash on linux, I'm on windows. Other suggestions were to use Windows Task Scheduler but that can only be set for a known time.
I came across the following code:
import os, sys, time
def main():
print "AutoRes is starting"
executable = sys.executable
args = sys.argv[:]
args.insert(0, sys.executable)
time.sleep(1)
print "Respawning"
os.execvp(executable, args)
if __name__ == "__main__":
main()
If I'm not mistaken that runs inside the code correct? Issue with that is my script is currently collecting data and I can't terminate to edit.
How about this?
from os import system
from time import sleep
while True: #manually terminate when you want to stop streaming
system('python streamer.py')
sleep(300) #sleep for 5 minutes
In the meanwhile, when something goes wrong in streamer.py , end it from there by invoking sys.exit(1)
Make sure this and streamer.py are in the same directory.