I am trying to get the ppid of the process that I want.
I used following code to get the pid
proc=subprocess.Popen('ps -ae | grep ruby', shell=True, stdout=subprocess.PIPE, )
output=proc.communicate()[0]
str = output.split()
Now in the str[0], I have the pid of the process say ruby, I want to get the parent process ID ppid and child process ID of the same process.
I need this solution to be run on Solaris as well as Red Hat Enterprise Linux 6.0
Is there any way to get that like getppid() and getchildid()? Or do I need to do it by grep command again and splitting?
Using this code is a bad idea. Your code will not work on solaris.
You can use 'psutil' library, that way you can keep your code independent of os.
https://github.com/giampaolo/psutil
p = psutil.Process(7055)
parent_pid = p.ppid()
I presume there's nothing wrong with os.getppid() .
Shrug.
http://docs.python.org/3/library/os.html#process-parameters
The answer depends on your system's ps command. On Linux, ps will include the PPID for each process with the -l flag (among others), so ps -ale | grep ruby will include the ruby process id in str[3] and ruby's PPID in str[4].
Related
I need one help regarding killing application in linux
As manual process I can use command -- ps -ef | grep "app_name" | awk '{print $2}'
It will give me jobids and then I will kill using command " kill -9 jobid".
I want to have python script which can do this task.
I have written code as
import os
os.system("ps -ef | grep app_name | awk '{print $2}'")
this collects jobids. But it is in "int" type. so I am not able to kill the application.
Can you please here?
Thank you
import subprocess
temp = subprocess.run("ps -ef | grep 'app_name' | awk '{print $2}'", stdin=subprocess.PIPE, shell=True, stdout=subprocess.PIPE)
job_ids = temp.stdout.decode("utf-8").strip().split("\n")
# sample job_ids will be: ['59899', '68977', '68979']
# convert them to integers
job_ids = list(map(int, job_ids))
# job_ids = [59899, 68977, 68979]
Then iterate through the job ids and kill them. Use os.kill()
for job_id in job_ids:
os.kill(job_id, 9)
Subprocess.run doc - https://docs.python.org/3/library/subprocess.html#subprocess.run
To kill a process in Python, call os.kill(pid, sig), with sig = 9 (signal number for SIGKILL) and pid = the process ID (PID) to kill.
To get the process ID, use os.popen instead of os.system above. Alternatively, use subprocess.Popen(..., stdout=subprocess.PIPE). In both cases, call the .readline() method, and convert the return value of that to an integer with int(...).
I'm encountering a lot of problems with this, I want to kill all my child processes without destroying my own process OR kill all the processes of some group OR get all the child processes PID... and all of this WITHOUT using either subprocess or psutil library in python anyone has any idea how
If you really cannot access those libraries, you can use os if push comes to shove.
For example:
my_pid = os.popen('ps --no-headers -C name_of_process').read(5)
if my_pid != "":
my_pid = int(my_pid)
os.kill(my_pid, signal.SIGTERM)
'name_of_process' would be the name of your executable
You might also want to look further at the commands ps and pkill.
Note: I am assuming you are using a Linux OS
My goal is simple: kick off rsync and DO NOT WAIT.
Python 2.7.9 on Debian
Sample code:
rsync_cmd = "/usr/bin/rsync -a -e 'ssh -i /home/myuser/.ssh/id_rsa' {0}#{1}:'{2}' {3}".format(remote_user, remote_server, file1, file1)
rsync_cmd2 = "/usr/bin/rsync -a -e 'ssh -i /home/myuser/.ssh/id_rsa' {0}#{1}:'{2}' {3} &".format(remote_user, remote_server, file1, file1)
rsync_path = "/usr/bin/rsync"
rsync_args = shlex.split("-a -e 'ssh -i /home/mysuser/.ssh/id_rsa' {0}#{1}:'{2}' {3}".format(remote_user, remote_server, file1, file1))
#subprocess.call(rsync_cmd, shell=True) # This isn't supposed to work but I tried it
#subprocess.Popen(rsync_cmd, shell=True) # This is supposed to be the solution but not for me
#subprocess.Popen(rsync_cmd2, shell=True) # Adding my own shell "&" to background it, still fails
#subprocess.Popen(rsync_cmd, shell=True, stdin=None, stdout=None, stderr=None, close_fds=True) # This doesn't work
#subprocess.Popen(shlex.split(rsync_cmd)) # This doesn't work
#os.execv(rsync_path, rsync_args) # This doesn't work
#os.spawnv(os.P_NOWAIT, rsync_path, rsync_args) # This doesn't work
#os.system(rsync_cmd2) # This doesn't work
print "DONE"
(I've commented out the execution commands only because I'm actually keeping all of my trials in my code so that I know what I've done and what I haven't done. Obviously, I would run the script with the right line uncommented.)
What happens is this...I can watch the transfer on the server and when it's finished, then I get a "DONE" printed to the screen.
What I'd like to have happen is a "DONE" printed immediately after issuing the rsync command and for the transfer to start.
Seems very straight-forward. I've followed details outlined in other posts, like this one and this one, but something is preventing it from working for me.
Thanks ahead of time.
(I have tried everything I can find in StackExchange and don't feel like this is a duplicate because I still can't get it to work. Something isn't right in my setup and need help.)
Here is verified example for Python REPL:
>>> import subprocess
>>> import sys
>>> p = subprocess.Popen([sys.executable, '-c', 'import time; time.sleep(100)'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT); print('finished')
finished
How to verify that via another terminal window:
$ ps aux | grep python
Output:
user 32820 0.0 0.0 2447684 3972 s003 S+ 10:11PM 0:00.01 /Users/user/venv/bin/python -c import time; time.sleep(100)
Popen() starts a child process—it does not wait for it to exit. You have to call .wait() method explicitly if you want to wait for the child process. In that sense, all subprocesses are background processes.
On the other hand, the child process may inherit various properties/resources from the parent such as open file descriptors, the process group, its control terminal, some signal configuration, etc—it may lead to preventing ancestors processes to exit e.g., Python subprocess .check_call vs .check_output or the child may die prematurely on Ctrl-C (SIGINT signal is sent to the foreground process group) or if the terminal session is closed (SIGHUP).
To disassociate the child process completely, you should make it a daemon. Sometimes something in between could be enough e.g., it is enough to redirect the inherited stdout in a grandchild so that .communicate() in the parent would return when its immediate child exits.
I encountered a similar issue while working with qnx devices and wanted a sub-process that runs independently of the main process and even runs after the main process terminates.
Here's the solution I found that actually works 'creationflags=subprocess.DETACHED_PROCESS':
import subprocess
import time
pid = subprocess.Popen(["python", "path_to_script\turn_ecu_on.py"], creationflags=subprocess.DETACHED_PROCESS)
time.sleep(15)
print("Done")
Link to the doc: https://docs.python.org/3/library/subprocess.html#subprocess.Popen
In Ubuntu the following commands keep working even if python app exits.
url = "https://www.youtube.com/watch?v=t3kcqTE6x4A"
cmd = f"mpv '{url}' && zenity --info --text 'you have watched {url}' &"
os.system(cmd)
I try to find the process ID on linux OS with python script, with following:
PID = Popen("ps -elf | grep <proc_name>| grep -v grep | awk '{print $4}'", shell=True, stdout=PIPE).stdout
pid = PID.read()
pid=int(pid)
However, the script does not work if there are more than one PIDs with the same
The program exits at the int() function due to '123\n146\n' is not the 10 based int
I then tried the following:
pid= Pid.read().split()
print len(pid)
print pid[0]
It seems to work with the python command line and forms an array of pid =['123','156'], but somehow, it does not work in the script.
any suggestion ? thanks
Are you trying to find out your own process id? If so, use os.getpid()
You could use subprocess.check_output() and str.splitlines():
from subprocess import check_output as qx
pids = map(int, qx(["pgrep", procname]).splitlines())
To do it without an external process you could try psutil:
import psutil # pip install psutil
pids = [p.pid for p in psutil.process_iter() if p.name == procname]
Experiment with p.name, p.cmdline and various comparisons with procname to get what you need in your particular case.
And there is also os.getpid() to return the current process id.
I am using python's multiprocessing module to spawn new process
as follows :
import multiprocessing
import os
d = multiprocessing.Process(target=os.system,args=('iostat 2 > a.txt',))
d.start()
I want to obtain pid of iostat command or the command executed using multiprocessing
module
When I execute :
d.pid
it gives me pid of subshell in which this command is running .
Any help will be valuable .
Thanks in advance
Similar to #rakslice, you can use psutil:
import signal, psutil
def kill_child_processes(parent_pid, sig=signal.SIGTERM):
try:
parent = psutil.Process(parent_pid)
except psutil.NoSuchProcess:
return
children = parent.children(recursive=True)
for process in children:
process.send_signal(sig)
Since you appear to be using Unix, you can use a quick ps command to get the details of the child processes, like I did here (this is Linux-specific):
import subprocess, os, signal
def kill_child_processes(parent_pid, sig=signal.SIGTERM):
ps_command = subprocess.Popen("ps -o pid --ppid %d --noheaders" % parent_pid, shell=True, stdout=subprocess.PIPE)
ps_output = ps_command.stdout.read()
retcode = ps_command.wait()
assert retcode == 0, "ps command returned %d" % retcode
for pid_str in ps_output.split("\n")[:-1]:
os.kill(int(pid_str), sig)
For your example you may use the subprocess package. By default it executes the command without shell (like os.system()) and provides a PID:
from subprocess import Popen
p = Popen('iostat 2 > a.txt', shell=True)
processId = p.pid
p.communicate() # to wait until the end
The Popen also provides ability to connect to standard input and output of the process.
note: before using shell=True be aware of the security considerations.
I think with the multiprocess module you might be out of luck since you are really forking python directly and are given that Process object instead of the process you are interested in at the bottom of the process tree.
An alternative way, but perhaps not optimal way, to get that pid is to use the psutil module to look it up using the pid obtained from your Process object. Psutil, however, is system dependent and will need to be installed separately on each of your target platforms.
Note: I'm not currently at a machine I typically work from, so I can't provide working code nor play around to find a better option, but will edit this answer when I can to show how you might be able to do this.
[me#localhost ~]$ echo $$
30399
[me#localhost ~]$ cat iostat.py
#!/usr/bin/env python3.4
import multiprocessing
import os
d = multiprocessing.Process(target=os.system,args=('iostat 2 > a.txt',))
d.start()
[me#localhost ~]$ ./iostat.py &
[1] 31068
[me#localhost ~]$ watch -n 3 'pstree -p 30399'
[me#localhost ~]$
This gave me the PID of iostat See image.