Python - wait for sysinputs - python

So I´m trying to create a python backend script for an electron app. I want to be able to continually pass system inputs to the python file, and have it run a function whenever the system input changes. I don´t want to have to run the python script each time as it takes a few seconds to load modules and data and just slows down the app.
I can´t find a good description anywhere on how to do this.
import sys
sysArg = []
def sysPrint(sysArgs):
print(sysArgs[1:])
while True:
if sys.argv <> sysArg:
sysPrint(sys.argv)
sysArg = sys.argv
This doesn´t work for me and also a "while True" loop doesn´t feel very safe CPU wise.
I´m also thinking that sys.argv might not be the right choice as that is perhaps only generated when calling the Python script?

If I don't misunderstand your question, you can just redirect the system output to a file,use nohup run program as a background process.
like this:
nohup some_program &> output.log" &
And then you can handle the output file like this:
import time
def tail(f):
f.seek(0,2)
while True:
line = f.readline()
if not line:
time.sleep(0.1)
continue
yield line
if __name__ == '__main__':
output_file= open("output.log","r")
for line in tail(output_file):
print(line)

Related

Not able to write to a file via command line

I am trying to log a python script. When the script is as follows there is no issue while logging:-
print('Test')
But when I enclose it in a while loop and sleep then it does not log the output for some reason.
while(1):
print('Test')
time.sleep(3600)
I am using Ubuntu and the command I run to log is:-
python3 script.py > /home/usr/Test.txt
So when you write to a file from bash like this, you will not get any output before your program has finished, so maybe it will be better to let python write to the file from within its own code.
Here is an example:
import time
while True:
new_data = 'hello fello!'
with open('file.txt', 'a+') as f:
f.write(new_data+'\n')
time.sleep(2)
Notice I added a newline \n after the new data to prevent everything being on the same line
the parameter 'a' in the open() means to append to the file, the + means also to read.
You need to flush the stream, to make sure it's written immediately.
import time
import sys
while True:
print('Test')
sys.stdout.flush()
time.seep(3600)

How to restart a python script using another?

('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'

Print output from python to C# application

I have made a C# app which calls a python script.
C# app uses Process object to call python script.
I also have redirected the sub-process standard output so I can process the output from python script.
But the problem is:
The output(via print function) from python will always arrive at once when the script terminates.
I want the output to arrive in real time while script running.
I can say I have tried almost all of method can get from google, like add flush of sys.out, redirect sysout in python, C# event driven message receiving or just using while to wait message etc,.
How to flush output of print function?
PyInstaller packaged application works fine in Console mode, crashes in Window mode
I am very wondering that like PyCharm or other python IDE, they run python script inside, but they can print the output one by one without hacking original python script, how they do that?
The python version is 2.7.
Hope to have advise.
Thank you!
I just use very stupid but working method to resolve it:
using thread to periodically flush the sys.out, the code piece is like this:
import sys
import os
import threading
import time
run_thread = False
def flush_print():
while run_thread:
# print 'something'
sys.stdout.flush()
time.sleep(1)
in main function:
if __name__ == '__main__':
thread = threading.Thread(target=flush_print)
run_thread = True
thread.start()
# my big functions with some prints, the function will block until completed
run_thread = False
thread.join()
Apparently this is ugly, but I have no better method to make work done .

Restart python script

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.

How to run and control a commandline program from python?

I have a python script which will give an output file. I need to feed this output file to a command line program. Is there any way I could call the commandline program and control it to process the file in python?
I tried to run this code
import os
import subprocess
import sys
proc = subprocess.Popen(["program.exe"], stdin=subprocess.PIPE)
proc.communicate(input=sys.argv[1]) #here the filename should be entered
proc.communicate(input=sys.argv[2]) #choice 1
proc.communicate(input=sys.argv[3]) #choice 2
is there any way I could enter the input coming from the commandline. And also though the cmd program opens the interface flickers after i run the code.
Thanks.
Note: platform is windows
Have a look at http://docs.python.org/library/subprocess.html. It's the current way to go when starting external programms. There are many examples and you have to check yourself which one fits your needs best.
You could do os.system(somestr) which lets you execute semestr as a command on the command line. However, this has been scrutinized over time for being insecure, etc (will post a link as soon as I find it).
As a result, it has been conventionally replaced with subprocess.popen
Hope this helps
depending on how much control you need, you might find it easier to use pexpect which makes parsing the output of the program rather easy and can also easily be used to talk to the programs stdin. Check out the website, they have some nice examples.
If your target program is expecting the input on STDIN, you can redirect using pipe:
python myfile.py | someprogram
As I just answered another question regarding subprocess, there is a better alternative!
Please have a look at the great library python sh, it is a full-fledged subprocess interface for Python that allows you to call any program as if it were a function, and more important, it's pleasingly pythonic.
Beside redirecting data stream with pipes, you can also process a command line such as:
mycode.py -o outputfile inputfilename.txt
You must import sys
import sys
and in you main function:
ii=1
infile=None
outfile=None
# let's process the command line
while ii < len(sys.argv):
arg = sys.argv[ii]
if arg == '-o':
ii = ii +1
outfile = sys.argv[ii]
else:
infile=arg
ii = ii +1
Of course, you can add some file checking, etc...

Categories

Resources