2

在 linux shell 中,我可以运行这个命令来杀死我的 python 脚本创建的每个进程(由 开始sudo python3 server.py):

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

我想将此添加到我的脚本中并在开始时结束任何先前的脚本进程,以避免出现套接字“地址已在使用”错误。

这是我的代码:

    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)

问题是这也会杀死新进程,因为它也是由相同的关键字启动的。

我怎样才能避免这种情况?

4

2 回答 2

2

您可以简单地杀死正在侦听端口 63 的程序,而不是按名称杀死程序。

以下命令为您提供侦听端口 63 的程序的 PID

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

或者更短的形式:

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];

       }
  }'
于 2013-08-27T14:34:28.550 回答
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)杀死它

于 2013-08-27T16:37:23.420 回答