for example I run a script
os.execv('script.py',('',))
As I read in docs this command starts a script from your current script by taking it's pid and reasigning it to run script.py. So I can get the pid of process.
The question is following:
After running execv I need to get the stdout of this script, and the only thing I know is the pid of process. Is it possible to perform this with python ? Any suggestions ? I need to use only execv()
Another possible solution redirecting the output to a file.
import os,sys
sys.stdout = open("./data.out","w")
os.dup2(sys.stdout.fileno(), 1)
os.execv('/usr/bin/python', ['python', './script.py'])
os.execv is just binding to execve system call. Thing that you need is a subprocess module:
import sys
import subprocess
proc = subprocess.Popen([sys.executable, 'script.py'],
stdout = subprocess.PIPE)
proc.wait()
print(proc.stdout.read())
See https://docs.python.org/2/library/subprocess.html
Related
In my python script I'm trying to run some long lasting download process, like in the example below, and need to find a PID of the process started by check_output:
out = subprocess.check_output(["rsync","-azh","file.log",...])
Is it possible to do?
You can run your subprocess using Popen instead:
import subprocess
proc = subprocess.Popen(["rsync","-azh","file.log",...], stdout=subprocess.PIPE)
out = proc.communicate()[0]
pid = proc.pid
Generally, Popen object gives you better control and more info of the subprocess, but requires a bit more to setup. (Not much, though.) You can read more in the official documentation.
I need help I am trying to open the terminal and type ifconfig and enter then read the output on a mac then il transition this later to kali but I am getting a error with the file path to terminal and I cant start it, here is my code.
import os,sys
#opens terminal
terminal = os.open('/Applications/Utilities/Terminal.app', os.O_RDWR|os.O_APPEND)
#writes ifconfig
os.write(terminal, 'ifconfig')
os.close(terminal)
I suggest you use subprocess
import subprocess
def popen(executable):
sb = subprocess.Popen(
'%s' % executable,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
)
stdout, stderr = sb.communicate()
return stdout, stderr, sb.returncode
you can pass ifconfig to this method and it will execute the command and return the output for you.
I agree with using subprocess. To add to Amin's answer, for something this simple that you just want the output from:
import subprocess
print(subprocess.check_output(['ifconfig']))
Edit:
What I was talking about in my comment is the new run function that returns a CompletedProcess class that holds all the relevant information for you. That way you no longer have to have three different variables holding your stdout, sterr and returncode.
I have an external executable file which I am trying to run from a Python script. CMD executable runs but without generating output. Probably it exit before output can be generated. Any suggestion about how to delay exit until outputs are generated?
import subprocess, sys
from subprocess import Popen, PIPE
exe_str = r"C:/Windows/System32/cmd C:/temp/calc.exe"
parent = subprocess.Popen(exe_str, stderr=subprocess.PIPE)
use subprocess.call, more info here:
import subprocess
subprocess.call(["C:\\temp\\calc.exe"])
or
import os
os.system('"C:/Windows/System32/notepad.exe"')
i hope it helps you...
The os.system method is depreciated and should not be used in new applications. The subprocess module is the pythonic way to do what you require.
Here is an example of some code I wrote a few weeks ago using subprocess to load files, the command you need to use to delay exit until data has been received and the launched program completes is wait():
import subprocess
cmd = "c:\\file.exe"
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, creationflags=0x08000000)
process.wait()
creationflags=0x08000000 is an optional parameter which suppresses the launch of a window, which can be useful if the program you are calling does not need to be directly seen.
Option 1
import subprocess
subprocess.call('C:\Windows\System32\calc.exe')
Option 2
subprocess.Popen(['C:\Windows\System32\calc.exe'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True).communicate()
Option 3
import os
os.system('C:\Windows\System32\calc.exe')
This worked for me after trying everything else:
Change the location of your python program to be the same as where the .exe is located.
And then the simple:
subprocess.call("calc.exe")
would work.
I can't find a simple answer for this: I'm using paramiko to log in and execute a number of processes remotely and I need the PIDs of each process in order to check on them at later times. There doesn't seem to be a function in paramiko to get the PID of an executed command, so I tried using the following:
stdin,stdout,stderr = ssh.exec_command('./someScript.sh &;echo $!;)
I thought that then parsing through the stdout would return the PID, but it doesn't. I'm assuming I should run the script in the background in order to have a PID (while it is running). Is there a more simple, obvious, way of getting the PID?
Here's a way to obtain the remote process ID:
def execute(channel, command):
command = 'echo $$; exec ' + command
stdin, stdout, stderr = channel.exec_command(command)
pid = int(stdout.readline())
return pid, stdin, stdout, stderr
I usually use the standard UNIX command pidof <command name>, when I check on the process later. AFAIK there is no simpler way.
OK, given your comment, you can solve it by wrapping your ./someScript.sh in a Python process that uses the subprocess module.
wrapper.py:
import subprocess
import sys
proc = subprocess.Popen(sys.argv[1])
print proc.pid
proc.wait() #probably
Then run
stdin,stdout,stderr = ssh.exec_command('./wrapper.py ./someScript.sh')
and read the output
When I execute a python script using subprocess.Popen(script, shell=True) in another python script, is it possible to alert python when the script completes running before executing other functions?
On a side note, can I get real-time output of the executed python script?
I can only get output from it doing command>output.txt but that's only after the whole process ends. stdout does not grep any ouput.
When you create a subprocess with Popen, it returns a subprocess.Popen object that has several methods for accessing subprocess status and data:
You can use poll() to determine whether a subprocess has finished. None indicates that the process has ended.
Output from a script while its running can be retrieved with communicate().
You can combine these two to create a script that monitors output from a subprocess and waits until its ready as follows:
import subprocess
p = subprocess.Popen((["python", "script.py"]), stdout=subprocess.PIPE)
while p.poll() is None:
(stdout, stderr) = p.communicate()
print stdout
You want to wait for the Popen to end? have you tried simply this:
popen = subprocess.Popen(script, shell=True)
popen.wait()
Have you considered using the external python script importing it as a module instead of spawning a subprocess?
As for the real-time output: try python -u ...