I have a small python file which just outputs a string:
#!/usr/bin/env python
print("This is a Test")
I can call this python script from another python script like so:
subprocess.call(['python', 'myPythonFile.py'])
And I can see the 'This is a Test' in my source python program.
But I want to call this script from a running Daemon as described here: https://gist.github.com/andreif/cbb71b0498589dac93cb
When I put the call to
subprocess.call(['python', 'myPythonFile.py'])
In MyDaemon.Run I DO NOT see the output.
How can I do this?
Try using the check_output function to see the actual output in your console
subprocess.check_output(['python', 'myPythonFile.py'])
You can find more info in the subprocess docs
subprocess.call can send its output to a file
tempfile = '/tmp/output.tmp' # better use mktemp
with open( tempfile, 'w') as output:
response = subprocess.call(
['python', 'myPythonFile.py'],
stdout=output,
stderr=output,
)
with open( tempfile, 'r') as output:
# read what happened from output, and decide what to do next
# or perhaps just feed it into your logging system
A daemon process is characterised by having no controlling terminal, because it is detached from whatever started the daemon. The daemon process is not connected to any console, by definition.
So, if that daemon runs another process:
I want to call this script from a running Daemon
then there is still no controlling terminal, and standard output is by default connected to the null device.
You will need to have the daemon process arrange to have its output somewhere. For example, a log file.
Try the python daemon library for a way to create daemons and nominate specific files (e.g. a log file you opened) to remain open in the daemon process.
Related
I am trying to write the codes to run a C executable using Python.
The C program can be run in the terminal just by calling ./myprogram and it will prompt a selection menu, as shown below:
1. Login
2. Register
Now, using Python and subprocess, I write the following codes:
import subprocess
subprocess.run(["./myprogram"])
The Python program runs but it shows nothing (No errors too!). Any ideas why it is happening?
When I tried:
import subprocess
subprocess.run(["ls"])
All the files in that particular directory are showing. So I assume this is right.
You have to open the subprocess like this:
import subprocess
cmd = subprocess.Popen(['./myprogram'], stdin=subprocess.PIPE)
This means that cmd will have a .stdin you can write to; print by default sends output to your Python script's stdout, which has no connection with the subprocess' stdin. So do that:
cmd.stdin.write('1\n') # tell myprogram to select 1
and then quite probably you should:
cmd.stdin.flush() # don't let your input stay in in-memory-buffers
or
cmd.stdin.close() # if you're done with writing to the subprocess.
PS If your Python script is a long-running process on a *nix system and you notice your subprocess has ended but is still displayed as a Z (zombie) process, please check that answer.
Maybe flush stdout?
print("", flush=True,end="")
I'm trying to spawn a subprocess that should still be running after the main process closed. This part works fine, but if I redirect the output of this process to a file, I can't start the script a second time because the process still blocks the log file.
This short example demonstrates the problem:
In this case the second process is "notepad" and is started by "other.cmd". While the main process/script is "test_it.py" which is started by "start_it.cmd".
start_it.cmd
#python test_it.py > test.log
test_it.py
import subprocess
from subprocess import DEVNULL, STDOUT
subprocess.Popen(["other.cmd"], stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT)
other.cmd
start notepad
When start_it.cmd is executed the second time, it will fail with this error message "The process cannot access the file because it is being used by another process".
How can I start the subprocess so that it doesn't block the log file?
A solution using a pipe.
multiplexer.py
with open('log.txt', 'a') as outputFile:
while True:
data = sys.stdin.read(1024)
if None == data:
break
outputFile.write(data)
start_it.cmd
#python test_it.py | python multiplexer.py
Everything else stays the same.
I found a solution that is close to what I originally intended:
subprocess.Popen("explorer other.cmd", shell=True)
By letting the explorer start the .cmd file this succesfully detaches the called .cmd from the original process. And thus doesn't keep the log file open.
I am attempting to to launch a python script from within another python script, but in a minimized console, then return control to the original shell.
I am able to open the required script in a new shell below, but it's not minimized:
#!/usr/bin/env python
import os
import sys
import subprocess
pyTivoPath="c:\pyTivo\pyTivo.py"
print "Testing: Open New Console"
subprocess.Popen([sys.executable, pyTivoPath], creationflags = subprocess.CREATE_NEW_CONSOLE)
print
raw_input("Press Enter to continue...")
Further, I will need to be able to later remotely KILL this shell from the original script, so I suspect I'll need to be explicit in naming the new process. Correct?
Looking for pointers, please. Thanks!
Note: python27 is mandatory for this application. Eventually will also need to work on Mac and Linux.
Do you need to have the other console open? If you now the commands to be sent, then I'd recommend using Popen.communicate(input="Shell commands") and it will automate the process for you.
So you could write something along the lines of:
# Commands to pass into subprocess (each command is separated by a newline)
commands = (
"command1\n" +
"command2\n"
)
# Your process
py_process = subprocess.Popen(*yourprocess_here*, stdin=PIPE, shell=True)
# Feed process the needed input
py_process.communicate(input=commands)
# Terminate when finished
py_process.terminate()
The code above will execute the process you specify and even send commands but it won't open a new console.
I currently have a script ("monitor") which monitors and outputs various system-type data to the screen. I have a Python program which is post processing that information when I use this command to pipe the monitor output to my Python program.
/usr/local/bin/monitor | /mnt/usbkey/pgms/myMonitorPgm.py
This much is working just fine.
I would like to use an os.system command (or something else??) to run the monitor script and create the pipe from within my Python program. This would run when I start my Python program and thus eliminate the need the above piping format/command.
Is this possible?
You should probably look at the subprocess module, in particular create a Popen object with stdout=PIPE then you can use communicate() or similar to read from the pipe within your Python program.
For example, you could do:
import subprocess
proc = subprocess.Popen( [ '/usr/local/bin/monitor' ], stdout=subprocess.PIPE )
stdout, _ = proc.communicate()
Now stdout will have the output from running the monitor program.
In my case what worked was:
with open('/tmp/mailbody', 'w') as f:
f.write(body)
os.system('/usr/bin/heirloom-mailx -s ' + subject + ' ' + mail + '< /tmp/mailbody')
I'm writing some code which involves running a few shell commands from Python and ideally, I would like to integrate the output from these commands into the logger that I'm using. I know I can divert stdout into a file / socket as follows:
call( '<a-shell-cmd>', shell=True, stdout=myFile )
but I'd rather not have the bind of opening a temporary file, looping over the file writing the output, closing the file, deleting the file etc. If there's anyway that I can send the output directly to the logger, it would seem a lot neater to me. Any ideas?
Use the subprocess module.
Tip: you can go to the documentation for a particular version of python via http://docs.python.org/release/<major>.<minor>/
From Python 2.7 and above:
output = subprocess.check_output(["command", "arg1"], shell=True)
In Python 2.4:
process = subprocess.Popen(["command", "arg1"], shell=True, stdout=subprocess.PIPE)
stdout,stderr = process.communicate()
# not shown: how to use Popen.poll() to wait for process death.
# while filling an output buffer
print stdout
Below Python 2.4:
output = os.popen('ls')
Use os.popen
output = os.popen('ls')
You can then log output or do it directly when calling the above.