Popen getting pid of newly run process
Since you are running it in the background (command &
), you get the interpreter's PID:
>> pipe = IO.popen("xcalc &")
>> pipe.pid
=> 11204
$ ps awx | grep "pts/8"
11204 pts/8 Z+ 0:00 [sh] <defunct>
11205 pts/8 S+ 0:00 xcalc
Drop the &
:
>> pipe = IO.popen("xcalc")
>> pipe.pid
=> 11206
$ ps awx | grep "pts/8"
11206 pts/8 S 0:00 xcalc
For the additional issue with the redirection, see @kares' answer
Opening a process with Popen and getting the PID
From the documentation at http://docs.python.org/library/subprocess.html:
Popen.pid The process ID of the child process.
Note that if you set the shell argument to True, this is the process
ID of the spawned shell.
If shell
is false, it should behave as you expect, I think.
If you were relying on shell
being True
for resolving executable paths using the PATH
environment variable, you can accomplish the same thing using shutil.which
instead, then pass the absolute path to Popen instead. (As an aside, if you are using Python 3.5 or newer, you should be using subprocess.run
rather than Popen.
How to get the pid of the process started by subprocess.run and kill it
Assign a variable to your subprocess
import os
import signal
import subprocess
exeFilePath = "C:/Users/test/test.exe"
p = subprocess.Popen(exeFilePath)
print(p.pid) # the pid
os.kill(p.pid, signal.SIGTERM) #or signal.SIGKILL
In same cases the process has children
processes. You need to kill all processes to terminate it. In that case you can use psutil
#python -m pip install —user psutil
import psutil
#remember to assign subprocess to a variable
def kills(pid):
'''Kills all process'''
parent = psutil.Process(pid)
for child in parent.children(recursive=True):
child.kill()
parent.kill()
#assumes variable p
kills(p.pid)
This will kill all processes in that PID
How to get PID of the subprocess with subprocess check_output
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.
Related Topics
Purpose of "Consider_All_Requests_Local" in Config/Environments/Development.Rb
How to Use "Gets" and "Gets.Chomp" in Ruby
Running Another Ruby Script from a Ruby Script
Understanding Ruby and Os I/O Buffering
Set Socket Timeout in Ruby Via So_Rcvtimeo Socket Option
String.Force_Encoding() in Ruby 1.8.7 (Or Rails 2.X)
Rails.Cache Error in Rails 3.1 - Typeerror: Can't Dump Hash With Default Proc
How to Run Rake Tasks Within a Ruby Script
In Ruby, Is There an Array Method That Combines 'Select' and 'Map'
Getaddrinfo: Nodename Nor Servname Provided, or Not Known
Rails Each Loop Insert Tag Every 6 Items
Checking If a Variable Is Defined in Sass
How to Convert Datetime.Now to Utc in Ruby
Running a Command from Ruby Displaying and Capturing the Output