Linux如何从命令行卡死的进程中退出?
Linux如何从命令行卡死的进程中退出?
不知道大家在使用Linux的时候,会不会遇到一些命令,有可能卡顿,有可能执行时间过长(比如使用 find 查找某个文件),这个时候我不想继续执行这个命令了,说来惭愧,我之前一直使用Ctrl+Z去终止这个命令,今天才知道,这样有很大的问题!
信号简介
一个进程在运行的时候,是能够接受内核发送的信号的,并且对这个信号做出自己的默认行为(没有被修改的话),

结合下面信号列表,我们所熟知的kill -9 <PID>,其实对应的就是发送一个sigkill信号杀死进程。
先看一下信号9,我们熟知的kill -9 <进程号>,就是让内核发送给进程终止信号,进程接收以后就会终止。
同理,我们也可以使用键盘发送信号 ,Ctrl + Z发送的信号只是挂起这个进程,Ctrl + C才是终止。这意味着,使用Ctrl + Z从终端退出的进程,并没有被释放
实验
接下来通过两个实验,看看Ctrl + Z(挂起)和Ctrl + C(停止)的区别。
find 查找文件
我们使用find命令从home目录查找某个文件,然后分别使用Ctrl + Z(挂起)和Ctrl + C(停止),看看他们的区别。
-
Ctrl + Z
运行find命令后,使用ctrl +Z 退出

此时使用
ps -t显示当前正在运行的进程的信息:
可以发现进程还存在着。
-
Ctrl + C
运行find命令后,使用ctrl +C

此时可以发现进程被彻底关闭了。
端口占用
在系统开启一个进程,这个进程会监听某个端口:

-
Ctrl + Z
在这之后,即使关闭终端,56868进程也没有被释放。

上图是在一个新的终端里使用sudo lsof -i :801查看端口的占用,发现这个进程并没有被释放,因此需 要使用kiil -9 56868释放进程。
-
Ctrl + C

进程被释放,端口也被释放。
原理简述

在 Linux 下,shell(比如 bash、zsh 等)本身就是一个进程。当你打开一个终端窗口或登录系统时,系统会启动一个 shell 进程,等待你的命令。
然后,当你在这个 shell 里输入命令并执行时,shell 会通过 fork() 创建一个子进程,再用 exec() 在这个子进程中加载并运行你要执行的命令程序。所以你在 shell 里启动的每一个命令进程,都是这个 shell 进程的子进程。
如果此时某个子进程还在执行,我直接关闭终端;又或者我使用了Ctrl + Z,暂停了某个子进程之后再关闭终端,这两种方式都不会导致子进程被杀死,对于前者,子进程会被linux 系统(systemd/init)"领养"到运行结束,对于后者,子进程也是会被领养,并且可以被kill -CONT [pid]恢复。
因此有两个好的避免僵尸进程的习惯:
- 如果不打算继续使用这个被退出的进程,使用
Ctrl + C退出。 - 关闭终端前,使用
Ctrl + C终止当前的进程。
更多与Linux信号相关的知识,感兴趣的可以移步:https://www.cnblogs.com/curiositywang/p/17994774
本文来自博客园,作者:CuriosityWang,转载请注明原文链接:https://www.cnblogs.com/curiositywang/p/17994756

浙公网安备 33010602011771号