通过壳层杀死过程而不杀死自己

时间:2022-04-30 16:24:48

In a linux shell, I can run this command to kill every process created by my python script (started by sudo python3 server.py):

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

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

I wanted to add this to my script and end any previous script process at start, to a avoid getting a socket "Address already in use" error.

我想把这个添加到我的脚本中,并在开始时结束任何先前的脚本进程,以避免获得一个“已经在使用中”错误的套接字“地址”。

Here's my code:

这是我的代码:

    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)

The problem is that this also kill the new process, because it's also started by the same keyword.

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

How can I avoid this?

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

2 个解决方案

#1


2  

Instead of killing the program by name you could simply kill the program that is listening on port 63.

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

The following command gives you the PID of the program listening on port 63

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

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

Or in a shorter form:

或以较短的形式:

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

Gluing everything together the command to kill the program listening on port 63 is the following:

将所有内容粘在一起,以杀死监听端口63的程序,如下所示:

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

Here the explanation:

这里的解释:

netstat -nlp outputs all the programs listening on some ports without resolving the port names.

netstat -nlp输出在某些端口上监听的所有程序,而不解析端口名称。

Thus one gets something like this:

因此我们会得到这样的结果:

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 
....

The awk command has the following meaning:

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

       }
  }'

#2


1  

You can use the psutil module to get process and networking information

您可以使用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()

Example Output on Windows, the module supports Linux too (list all listening processes):

示例输出在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')]

With all this information you can find your process and even kill it with the psutil.Process methods terminate() (sends SIGTERM signal) or kill() (sends SIGKILL signal, just like kill -9)

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

#1


2  

Instead of killing the program by name you could simply kill the program that is listening on port 63.

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

The following command gives you the PID of the program listening on port 63

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

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

Or in a shorter form:

或以较短的形式:

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

Gluing everything together the command to kill the program listening on port 63 is the following:

将所有内容粘在一起,以杀死监听端口63的程序,如下所示:

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

Here the explanation:

这里的解释:

netstat -nlp outputs all the programs listening on some ports without resolving the port names.

netstat -nlp输出在某些端口上监听的所有程序,而不解析端口名称。

Thus one gets something like this:

因此我们会得到这样的结果:

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 
....

The awk command has the following meaning:

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

       }
  }'

#2


1  

You can use the psutil module to get process and networking information

您可以使用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()

Example Output on Windows, the module supports Linux too (list all listening processes):

示例输出在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')]

With all this information you can find your process and even kill it with the psutil.Process methods terminate() (sends SIGTERM signal) or kill() (sends SIGKILL signal, just like kill -9)

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