天天看點

linux下殺死所有子程序,subprocess.popen.kill殺死所有子程序

subprocess.popen.kill殺死所有子程序

釋出時間:2020-02-22 11:19:49編輯:admin閱讀(998)

一、使用subprocess子產品

使用subprocess子產品可建立子程序。subprocess. Popen ( args , bufsize=0 , executable=None , stdin=None , stdout=None , stderr=None , preexec_fn=None , close_fds=False , shell=False , cwd=None , env=None , universal_newlines=False , startupinfo=None , creationflags=0 )

subprocess.Popen(['google-chrome',"http://www.baidu.com"])可打開chrome并顯示百度網頁。

subprocess.Popen.pid可顯示子程序的id,但這隻是打開的shell的id,如果此時使用pid.kill是無法殺掉所有子程序的。

殺掉所有子程序,代碼:import sys, os, subprocess, time, signal

p = subprocess.Popen(['google-chrome',"http://www.baidu.com"], close_fds=True, preexec_fn = os.setsid)

print p.pid

time.sleep(5)

# p.kill() #無法殺掉所有子程序,隻能殺掉子shell的程序

# p.terminate()  #無法殺掉所有子程序

os.killpg( p.pid,signal.SIGUSR1)

time.sleep(3)

注意:

close_fds=True,此時除了檔案描述符為0 , 1 and 2,其他子程序都要被殺掉。( Linux中所有的程序都是程序0的子程序。

pid=1的是init,核心完成之後啟動的第一個程序,然後init根據/etc/inittab的内容再去啟動其它程序。)

os.setsid(): 使獨立于終端的程序(不響應sigint,sighup等),使脫離終端。

SIGUSR1: 使用者自定義信号

os.killpg( p.pid,signal.SIGUSR1): 發送SIGUSR1信号到組程序p.pid

二、封裝subprocess 函數

最近使用python 調用ansible指令,來監測系統相關服務。發現到達指定時間,ansible程序沒有殺掉。導緻伺服器卡死。

後來嘗試 使用os.killpg ,發現可以殺掉ansible 子程序。

完整代碼如下:#!/usr/bin/env python3

# coding: utf-8

import os

import time

import signal

import subprocess

def execute_linux2(cmd, timeout=10, skip=False):

"""

執行linux指令,傳回list

:param cmd: linux指令

:param timeout: 逾時時間,生産環境, 特别卡, 是以要3秒

:param skip: 是否跳過逾時限制

:return: list

"""

p = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE,shell=True,close_fds=True,preexec_fn=os.setsid)

t_beginning = time.time()  # 開始時間

while True:

if p.poll() is not None:

break

seconds_passed = time.time() - t_beginning

if not skip:

if seconds_passed > timeout:

# p.terminate()

# p.kill()

# raise TimeoutError(cmd, timeout)

print('錯誤, 指令: {},本地執行逾時!'.format(cmd))

# 當shell=True時,隻有os.killpg才能kill子程序

try:

# time.sleep(1)

os.killpg(p.pid, signal.SIGUSR1)

except Exception as e:

pass

return False

result = p.stdout.readlines()  # 結果輸出清單

return result

本文參考連結:

關鍵字: