2013-08-27 125 views
2

在Linux命令,我可以运行此命令来杀死我的Python脚本创建的每个过程(由sudo python3 server.py启动):杀过程中没有杀死自己

sudo kill -9 `ps -ef | grep server.py |grep -v "grep"|awk '{{print $2}}' 

我想加入到我的脚本并在开始时结束之前的任何脚本进程,以避免出现套接字“Address already in use”错误。

这里是我的代码:

try: 
     application.listen(port=63) 
    except OSError as e: 
     if e.errno == errno.EADDRINUSE: 
      cmd = 'sudo kill -9 `ps -ef | grep server.py |grep -v "grep"|awk \'{{print $2}}\'`' 
      print('try to kill previous',cmd) 
      import os 
      os.system(cmd) 

的问题是,这也杀死了新的进程,因为它也是由相同的关键字开始。

我该如何避免这种情况?

+2

首先全部:这是一个坏主意。如果你不小心杀死了一些重要的东西呢?其次:你正在检查'EADDRINUSE'。即使在后台没有运行'server.py',你的代码可能会抛出它,因为OS没有足够的时间来重置套接字。一般你做错了! – freakish

+0

我想知道如何去做。我不认为这是危险或不危险,或更安全的方式来完成这项任务? – user2003548

+1

我喜欢避免在python中使用命令行,大多数情况下都有一个有用的模块,比如['psutil'](http://code.google。com/p/psutil /)在这种情况下,不幸的是我几乎没有任何经验,但你可以访问进程和网络信息(也许得到该端口上的程序绑定的pid) – KurzedMetal

回答

2

而不是按名称查杀程序,你可以简单地 杀死在端口监听程序63

下面的命令为您提供了程序侦听端口63

netstat --numeric-ports --listening --program | awk '{if (match($4, ":63$")) { split($NF, a, "/"); print a[1];}}' 

的PID或者以更短的形式:

netstat -nlp | awk '{if (match($4, ":63$")) {split($NF, a, "/"); print a[1];}}' 

将所有东西粘在一起命令终止侦听端口63的程序如下:

sudo kill -9 `netstat -nlp | awk '{if (match($4, ":63$")) {split($NF, a, "/"); print a[1];}}'` 

这里的解释:

netstat -nlp输出的所有程序上的一些端口上侦听没有解决端口名称。

因此,人们得到这样的事情:

Proto Recv-Q Send-Q Local Address   Foreign Address   State  PID/Program name 
tcp  0  0 127.0.0.1:9000   0.0.0.0:*    LISTEN  2096/php-fpm.conf) 
tcp  0  0 127.0.0.1:63   0.0.0.0:*    LISTEN  2263/memcached 
tcp  0  0 0.0.0.0:36815   0.0.0.0:*    LISTEN  1748/rpc.statd 
.... 

awk命令具有以下含义:

awk '{ 
     # check if field "Local Address" ends with ":63" 
     if (match($4, ":63$")) { 

      # split the field "PID/Program name" 
      # into the array a based on delimiter "/" 
      split($NF, a, "/"); 

      # print the PID 
      print a[1]; 

     } 
    }' 
+0

有多个进程时它不工作,如果子进程没有被杀死,地址将不会被释放。 – user2003548

+0

你是否已经试图杀死所有的孩子?这里有一些提示要这样做:http://stackoverflow.com/questions/392022/best-way-to-kill-all-child-processes/6481337#6481337 – wooghie

1

可以使用psutil模块获取进程和网络信息

import psutil 
import pprint 

for process in psutil.process_iter(): 
    ### find which ports is the listening (if any) 
    listening_ports = [conn for conn in process.get_connections() if conn.status == psutil.CONN_LISTEN] 
    if len(listening_ports) > 0: 
     print("PID: {}, Process Name: {}".format(process.pid, process.name)) 
     print("Connections:") 
     pprint.pprint(listening_ports) 
    ### You could check the desired process and terminate/kill it 
    # process.terminate() 

示例在Windows上输出,该模块也支持Linux(全部列出监听进程):

PID: 664, Process Name: lsass.exe 
Connections: 
[connection(fd=-1, family=2, type=1, laddr=('0.0.0.0', 49155), raddr=(), status='LISTEN'), 
connection(fd=-1, family=23, type=1, laddr=('::', 49155), raddr=(), status='LISTEN')] 
PID: 904, Process Name: svchost.exe 
Connections: 
[connection(fd=-1, family=2, type=1, laddr=('0.0.0.0', 135), raddr=(), status='LISTEN'), 
connection(fd=-1, family=23, type=1, laddr=('::', 135), raddr=(), status='LISTEN')] 
PID: 1712, Process Name: SpiderOak.exe 
Connections: 
[connection(fd=-1, family=2, type=1, laddr=('127.0.0.1', 49201), raddr=(), status='LISTEN'), 
connection(fd=-1, family=2, type=1, laddr=('0.0.0.0', 49258), raddr=(), status='LISTEN')] 

有了这些信息,你可以找到你的进程,甚至与psutil.Process方法terminate()杀死它(发送SIGTERM信号)或kill()(发送SIGKILL信号,就像kill -9

+0

这将是一个备份解决方案,缺点是必须使用额外的插件。 – user2003548