标签 进程 下的文章

一个简单的教学展示,教你如何找到正在运行中的进程 ID 并杀死它,你可以使用终端或者 GUI,这个方法适用于各类 Linux 发行版。

你的 Linux 系统中运行的应用可能会让你的电脑变慢,特别是你的电脑配置较低的时候。在 Linux (以及所有其他 OS)中,程序或者应用都携带一个特别的 PID (进程 ID)可供你简单地分辨它们。

然而,大部分 Linux 初学者用户并不知道如何在 Linux 中寻找运行中的进程并杀死它。在这篇指南中,我们将会解释用不同的方法以杀死 Linux 中的运行进程。这包括了使用终端和 GUI 的方法。

记住,你只应该杀死未响应的进程,或者你发现应用无法被正常关闭 (针对基于 GUI 的应用)。

如何在 Linux 中找到 PID 并杀掉它们

在这一部分中,我们首先应该先学会如何找到运行进程的 PID,然后再学习用以杀掉它们的命令:

找到正在运行中的进程

你可以使用命令 top 来列出所有正在进行中的进程和它们的 PID,以及其他细节。程序 top 在所有 Linux 发行版和所有基于 Unix 的系统中都是默认安装了的。

top

Top program output

同样地,你可以执行命令 ps 附带额外选项来获取某个指定的进程的 PID。例如,你可以使用以下命令来获得 firefox 的 PID。

ps -el | grep -i firefox

Firefox process id using ps command - example

现在你已经找到 PID 了,让我们看看你该如何杀掉它。

杀死运行中的进程

使用以下命令,你可以通过进程的名字或者 PID 来杀掉这个正在运行中的进程:

  • killall:通过运行进程的名字来杀死进程
  • kill:通过 PID 来杀死进程

现在,让我们首先使用进程 killall 通过 Firefox 这个名字来杀死它的,命令如下:

killall -9 firefox
  • 参数 -9 发送了信号 SIGKILL 通知 OS 来终止这个进程。
  • 使用以下命令,你也可以列出一些别的信号。
kill -l

同样地,如果你想要通过 PID 来杀死进程,你可以用以下命令:

kill -9 <PID>

在这个例子中,命令会长这样:

kill -9 33665

让我们看看在不同发行版中,你该如何使用图形用户界面(GUI)来杀死任意进程或应用。

通过 GUI 寻找 PID 并杀掉

现在有很多图形界面程序可以枚列进程。大部分 Linux 发行版的桌面环境中已经携带了它们。我们在这里列举出了一些。

GNOME(在 Ubuntu、Fedora 工作站等) & 在 Linux Mint 中

在应用菜单中搜索 “system monitor” 并打开它(LCTT 译注:中文桌面环境也可以搜 “system monitor”,我在 Ubuntu 里试过了)。在 “ 进程 Processes ” 标签页下找到你的进程,右击进程名字打开快捷菜单,选择选项 “ 杀死 Kill ”。

Kill a process in Linux using gnome system monitor

KDE Plasma(Kubuntu、Fedora-KDE 或任何基于 Plasma 的发行版)

在应用菜单中搜索并启动 “system monitor”。这会打开以下程序。在左边菜单栏点击“ 进程 Processes ” ,你因该能看见一列正在运行的程序。你可以右击列表里的进程或应用并选择“ 杀死 Kill ”来终止进程。

System monitor in KDE Plasma

Xfce 桌面

Xfce 桌面可以完成这项任务的原生应用是 任务管理器 Task Manager ,你可以通过 “ 应用 Application > 系统 System > 任务管理器 Task manager ” 来找到它。右击进程名字然后选择“ 杀死 Kill ”来终止应用或进程。

Xfce task manager to kill a process

如何在其他桌面或发行版上杀死一个进程或程序

如果你找不到任何相似的程序,你可以选择使用终端的方法。或者,你可以使用以下命令来安装 gnome-system-monitor。

Ubuntu 以及相关发行版:

sudo apt install gnome-system-monitor

Fedora 以及其相关的发行版:

sudo dnf install gnome-system-monitor

还有 Arch Linux:

sudo pacman -S gnome-system-monitor

总结一下

这就是你该如何在 Linux 中找到一个运行中的进程的 PID 并杀死它。我们已经解释了不同的方法:你可以通过名字或者 PID 来杀死进程。我希望这对你有所帮助。


via: https://www.debugpoint.com/find-process-id-kill-linux/

作者:Arindam 选题:lkxed 译者:yzuowei 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

了解如何使用 ps、kill 和 killall 命令来终止进程并回收系统资源。

 title=

在 Linux 中,每个程序和 守护程序 daemon 都是一个“ 进程 process ”。 大多数进程代表一个正在运行的程序。而另外一些程序可以派生出其他进程,比如说它会侦听某些事件的发生,然后对其做出响应。并且每个进程都需要一定的内存和处理能力。你运行的进程越多,所需的内存和 CPU 使用周期就越多。在老式电脑(例如我使用了 7 年的笔记本电脑)或轻量级计算机(例如树莓派)上,如果你关注过后台运行的进程,就能充分利用你的系统。

你可以使用 ps 命令来查看正在运行的进程。你通常会使用 ps 命令的参数来显示出更多的输出信息。我喜欢使用 -e 参数来查看每个正在运行的进程,以及 -f 参数来获得每个进程的全部细节。以下是一些例子:

$ ps
    PID TTY          TIME CMD
  88000 pts/0    00:00:00 bash
  88052 pts/0    00:00:00 ps
  88053 pts/0    00:00:00 head
$ ps -e | head
    PID TTY          TIME CMD
      1 ?        00:00:50 systemd
      2 ?        00:00:00 kthreadd
      3 ?        00:00:00 rcu_gp
      4 ?        00:00:00 rcu_par_gp
      6 ?        00:00:02 kworker/0:0H-events_highpri
      9 ?        00:00:00 mm_percpu_wq
     10 ?        00:00:01 ksoftirqd/0
     11 ?        00:00:12 rcu_sched
     12 ?        00:00:00 migration/0
$ ps -ef | head
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 13:51 ?        00:00:50 /usr/lib/systemd/systemd --switched-root --system --deserialize 36
root           2       0  0 13:51 ?        00:00:00 [kthreadd]
root           3       2  0 13:51 ?        00:00:00 [rcu_gp]
root           4       2  0 13:51 ?        00:00:00 [rcu_par_gp]
root           6       2  0 13:51 ?        00:00:02 [kworker/0:0H-kblockd]
root           9       2  0 13:51 ?        00:00:00 [mm_percpu_wq]
root          10       2  0 13:51 ?        00:00:01 [ksoftirqd/0]
root          11       2  0 13:51 ?        00:00:12 [rcu_sched]
root          12       2  0 13:51 ?        00:00:00 [migration/0]

最后的例子显示最多的细节。在每一行,UID(用户 ID)显示了该进程的所有者。PID(进程 ID)代表每个进程的数字 ID,而 PPID(父进程 ID)表示其父进程的数字 ID。在任何 Unix 系统中,进程是从 1 开始编号,是内核启动后运行的第一个进程。在这里,systemd 是第一个进程,它催生了 kthreadd,而 kthreadd 还创建了其他进程,包括 rcu_gprcu_par_gp 等一系列进程。

使用 kill 命令来管理进程

系统会处理大多数后台进程,所以你不需要操心这些进程。你只需要关注那些你所运行的应用创建的进程。虽然许多应用一次只运行一个进程(如音乐播放器、终端模拟器或游戏等),但其他应用则可能创建后台进程。其中一些应用可能当你退出后还在后台运行,以便下次你使用的时候能快速启动。

当我运行 Chromium(作为谷歌 Chrome 浏览器所基于的开源项目)时,进程管理便成了问题。 Chromium 在我的笔记本电脑上运行非常吃力,并产生了许多额外的进程。现在我仅打开五个选项卡,就能看到这些 Chromium 进程:

$ ps -ef | fgrep chromium
jhall      66221   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
jhall      66230   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
[...]
jhall      66861   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
jhall      67329   65132  0 15:45 pts/0    00:00:00 grep -F chromium

我已经省略一些行,其中有 20 个 Chromium 进程和一个正在搜索 “chromium" 字符的 grep 进程。

$ ps -ef | fgrep chromium | wc -l
21

但是在我退出 Chromium 之后,这些进程仍旧运行。如何关闭它们并回收这些进程占用的内存和 CPU 呢?

kill 命令能让你终止一个进程。在最简单的情况下,你告诉 kill 命令终止你想终止的进程的 PID。例如,要终止这些进程,我需要对 20 个 Chromium 进程 ID 都执行 kill 命令。一种方法是使用命令行获取 Chromium 的 PID,而另一种方法针对该列表运行 kill

$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}'
66221
66230
66239
66257
66262
66283
66284
66285
66324
66337
66360
66370
66386
66402
66503
66539
66595
66734
66848
66861
69702

$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}' > /tmp/pids
$ kill $(cat /tmp/pids)

最后两行是关键。第一个命令行为 Chromium 浏览器生成一个进程 ID 列表。第二个命令行针对该进程 ID 列表运行 kill 命令。

介绍 killall 命令

一次终止多个进程有个更简单方法,使用 killall 命令。你或许可以根据名称猜测出,killall 会终止所有与该名字匹配的进程。这意味着我们可以使用此命令来停止所有流氓 Chromium 进程。这很简单:

$ killall /usr/lib64/chromium-browser/chromium-browser

但是要小心使用 killall。该命令能够终止与你所给出名称相匹配的所有进程。这就是为什么我喜欢先使用 ps -ef 命令来检查我正在运行的进程,然后针对要停止的命令的准确路径运行 killall

你也可以使用 -i--interactive 参数,来让 killkill 在停止每个进程之前提示你。

killall 还支持使用 -o--older-than 参数来查找比特定时间更早的进程。例如,如果你发现了一组已经运行了好几天的恶意进程,这将会很有帮助。又或是,你可以查找比特定时间更晚的进程,例如你最近启动的失控进程。使用 -y--young-than 参数来查找这些进程。

其他管理进程的方式

进程管理是系统维护重要的一部分。在我作为 Unix 和 Linux 系统管理员的早期职业生涯中,杀死非法作业的能力是保持系统正常运行的关键。在如今,你可能不需要亲手在 Linux 上的终止流氓进程,但是知道 killkillall 能够在最终出现问题时为你提供帮助。

你也能寻找其他方式来管理进程。在我这个案例中,我并不需要在我退出浏览器后,使用 killkillall 来终止后台 Chromium 进程。在 Chromium 中有个简单设置就可以进行控制:

 title=

不过,始终关注系统上正在运行哪些进程,并且在需要的时候进行干预是一个明智之举。


via: https://opensource.com/article/20/1/linux-kill-killall

作者:Jim Hall 选题:lujun9972 译者:wyxplus 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

过去,我们写了三篇不同的文章来使用 Linux 命令来识别这些进程。

你可以通过下面相关的 URL 立即访问:

本教程中包含两个脚本,它们可以帮助你确定 Linux 上高 CPU/内存消耗进程的运行时间。

该脚本将显示进程 ID、进程的所有者、进程的名称以及进程的运行时间。这将帮助你确定哪些(必须事先完成)作业正在超时运行。这可以使用 ps 命令来实现。

什么是 ps 命令

ps 进程状态 processes status ,它显示有关系统上活动/正在运行的进程的信息。

它提供了当前进程的快照以及详细信息,例如用户名、用户 ID、CPU 使用率、内存使用率、进程开始日期和时间等。

1)检查高 CPU 消耗进程在 Linux 上运行了多长时间的 Bash 脚本

该脚本将帮助你确定高 CPU 消耗进程在 Linux 上运行了多长时间。

# vi /opt/scripts/long-running-cpu-proc.sh

#!/bin/bash
ps -eo pid,user,ppid,%mem,%cpu,cmd --sort=-%cpu | head | tail -n +2 | awk '{print $1}' > /tmp/long-running-processes.txt
echo "--------------------------------------------------"
echo "UName     PID  CMD            Process_Running_Time"
echo "--------------------------------------------------"
for userid in `cat /tmp/long-running-processes.txt`
do
username=$(ps -u -p $userid | tail -1 | awk '{print $1}')
pruntime=$(ps -p $userid -o etime | tail -1)
ocmd=$(ps -p $userid | tail -1 | awk '{print $4}')
echo "$username $userid $ocmd $pruntime"
done | column -t
echo "--------------------------------------------------"

long-running-cpu-proc.sh 设置可执行的 Linux 文件权限

# chmod +x /opt/scripts/long-running-cpu-proc.sh

运行此脚本时,你将获得类似以下的输出:

# sh /opt/scripts/long-running-cpu-proc.sh

----------------------------------------------------
UName     PID  CMD       Process_Running_Time
----------------------------------------------------
daygeek  5214  Web       01:18:48
daygeek  5748  Web       01:08:20
daygeek  8043  inkscape  22:11
daygeek  5269  Web       01:18:31
daygeek  1712  Web       10:44:50
daygeek  5335  RDD       01:17:54
daygeek  1639  firefox   10:44:51
daygeek  7793  nautilus  24:14
daygeek  6301  Web       57:40
----------------------------------------------------

2)检查高内存消耗进程在 Linux 上运行了多长时间的 Bash 脚本

该脚本将帮助你确定最大的内存消耗进程在 Linux 上运行了多长时间。

# sh /opt/scripts/long-running-memory-proc.sh

#!/bin/bash
ps -eo pid,user,ppid,%mem,%cpu,cmd --sort=-%mem | head | tail -n +2 | awk '{print $1}' > /tmp/long-running-processes-1.txt
echo "--------------------------------------------------"
echo "UName     PID  CMD          Process_Running_Time"
echo "--------------------------------------------------"
for userid in `cat /tmp/long-running-processes-1.txt`
do
username=$(ps -u -p $userid | tail -1 | awk '{print $1}')
pruntime=$(ps -p $userid -o etime | tail -1)
ocmd=$(ps -p $userid | tail -1 | awk '{print $4}')
echo "$username $userid $ocmd $pruntime"
done | column -t
echo "--------------------------------------------------"

long-running-memory-proc.sh 设置可执行的 Linux 文件权限。

# chmod +x /opt/scripts/long-running-memory-proc.sh

运行此脚本时,你将获得类似以下的输出:

# sh /opt/scripts/long-running-memory-proc.sh

----------------------------------------------------
UName    PID   CMD       Process_Running_Time
----------------------------------------------------
daygeek  1639  firefox   10:44:56
daygeek  2997  Web       10:39:54
daygeek  5269  Web       01:18:37
daygeek  1712  Web       10:44:55
daygeek  8043  inkscape  22:17
daygeek  5214  Web       01:18:54
daygeek  1898  Web       10:44:48
daygeek  1129  Xorg      10:45:07
daygeek  6301  Web       57:45
----------------------------------------------------

via: https://www.2daygeek.com/bash-script-to-check-how-long-the-high-cpu-memory-consumption-processes-runs-on-linux/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:geekpi 校对:校对者ID

本文由 LCTT 原创编译,Linux中国 荣誉推出

通过这些关键的命令来全程管理你的应用。

一般来说,应用程序进程的生命周期有三种主要状态:启动、运行和停止。如果我们想成为称职的管理员,每个状态都可以而且应该得到认真的管理。这八个命令可用于管理进程的整个生命周期。

启动进程

启动进程的最简单方法是在命令行中键入其名称,然后按回车键。如果要启动 Nginx web 服务器,请键入 nginx 。也许您只是想看看其版本。

alan@workstation:~$ nginx

alan@workstation:~$ nginx -v
nginx version: nginx/1.14.0

查看您的可执行路径

以上启动进程的演示是假设可执行文件位于您的可执行路径中。理解这个路径是可靠地启动和管理进程的关键。管理员通常会为他们想要的目的定制这条路径。您可以使用 echo $PATH 查看您的可执行路径。

alan@workstation:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

WHICH

使用 which 命令查看可执行文件的完整路径。

alan@workstation:~$ which nginx
/opt/nginx/bin/nginx

我将使用流行的 web 服务器软件 Nginx 作为我的例子。假设安装了 Nginx。如果执行 which nginx 的命令什么也不返回,那么是找不到 Nginx 了,因为它只搜索您指定的可执行路径。有三种方法可以补救一个进程不能简单地通过名字启动的情况。首先是键入完整路径 —— 虽然,我不情愿输入全部路径,您会吗?

alan@workstation:~$ /home/alan/web/prod/nginx/sbin/nginx -v
nginx version: nginx/1.14.0

第二个解决方案是将应用程序安装在可执行文件路径中的目录中。然而,这有时可能是办不到的,特别是如果您没有 root 权限。

第三个解决方案是更新您的可执行路径环境变量,包括要使用的特定应用程序的安装目录。这个解决方案是与 shell 相关的。例如,Bash 用户需要在他们的 .bashrc 文件中编辑 PATH= 行。

PATH="$HOME/web/prod/nginx/sbin:$PATH"

现在,重复您的 echowhich 命令或者尝试检查版本。容易多了!

alan@workstation:~$ echo $PATH
/home/alan/web/prod/nginx/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

alan@workstation:~$ which nginx
/home/alan/web/prod/nginx/sbin/nginx

alan@workstation:~$ nginx -v                                                
nginx version: nginx/1.14.0

保持进程运行

NOHUP

注销或关闭终端时,进程可能不会继续运行。这种特殊情况可以通过在要使用 nohup 命令放在要运行的命令前面让进程持续运行。此外,附加一个& 符号将会把进程发送到后台,并允许您继续使用终端。例如,假设您想运行 myprogram.sh

nohup myprogram.sh &

nohup 会返回运行进程的 PID。接下来我会更多地谈论 PID。

管理正在运行的进程

每个进程都有一个唯一的进程标识号 (PID) 。这个数字是我们用来管理每个进程的。我们还可以使用进程名称,我将在下面演示。有几个命令可以检查正在运行的进程的状态。让我们快速看看这些命令。

PS

最常见的是 ps 命令。ps 的默认输出是当前终端中运行的进程的简单列表。如下所示,第一列包含 PID。

alan@workstation:~$ ps
PID TTY          TIME CMD
23989 pts/0    00:00:00 bash
24148 pts/0    00:00:00 ps

我想看看我之前启动的 Nginx 进程。为此,我告诉 ps 给我展示每一个正在运行的进程(-e)和完整的列表(-f)。

alan@workstation:~$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Aug18 ?        00:00:10 /sbin/init splash
root         2     0  0 Aug18 ?        00:00:00 [kthreadd]
root         4     2  0 Aug18 ?        00:00:00 [kworker/0:0H]
root         6     2  0 Aug18 ?        00:00:00 [mm_percpu_wq]
root         7     2  0 Aug18 ?        00:00:00 [ksoftirqd/0]
root         8     2  0 Aug18 ?        00:00:20 [rcu_sched]
root         9     2  0 Aug18 ?        00:00:00 [rcu_bh]
root        10     2  0 Aug18 ?        00:00:00 [migration/0]
root        11     2  0 Aug18 ?        00:00:00 [watchdog/0]
root        12     2  0 Aug18 ?        00:00:00 [cpuhp/0]
root        13     2  0 Aug18 ?        00:00:00 [cpuhp/1]
root        14     2  0 Aug18 ?        00:00:00 [watchdog/1]
root        15     2  0 Aug18 ?        00:00:00 [migration/1]
root        16     2  0 Aug18 ?        00:00:00 [ksoftirqd/1]
alan     20506 20496  0 10:39 pts/0    00:00:00 bash
alan     20520  1454  0 10:39 ?        00:00:00 nginx: master process nginx
alan     20521 20520  0 10:39 ?        00:00:00 nginx: worker process
alan     20526 20506  0 10:39 pts/0    00:00:00 man ps
alan     20536 20526  0 10:39 pts/0    00:00:00 pager
alan     20564 20496  0 10:40 pts/1    00:00:00 bash

您可以在上面 ps 命令的输出中看到 Nginx 进程。这个命令显示了将近 300 行,但是我在这个例子中缩短了它。可以想象,试图处理 300 行过程信息有点混乱。我们可以将这个输出输送到 grep,过滤一下仅显示 nginx。

alan@workstation:~$ ps -ef |grep nginx
alan     20520  1454  0 10:39 ?        00:00:00 nginx: master process nginx
alan     20521 20520  0 10:39 ?        00:00:00 nginx: worker process

确实更好了。我们可以很快看到,Nginx 有 20520 和 20521 的 PID。

PGREP

pgrep 命令更加简化单独调用 grep 遇到的问题。

alan@workstation:~$ pgrep nginx
20520
20521

假设您在一个托管环境中,多个用户正在运行几个不同的 Nginx 实例。您可以使用 -u 选项将其他人排除在输出之外。

alan@workstation:~$ pgrep -u alan nginx
20520
20521

PIDOF

另一个好用的是 pidof。此命令将检查特定二进制文件的 PID,即使另一个同名进程正在运行。为了建立一个例子,我将我的 Nginx 复制到第二个目录,并以相应的路径前缀启动。在现实生活中,这个实例可能位于不同的位置,例如由不同用户拥有的目录。如果我运行两个 Nginx 实例,则pidof 输出显示它们的所有进程。

alan@workstation:~$ ps -ef |grep nginx
alan     20881  1454  0 11:18 ?        00:00:00 nginx: master process ./nginx -p /home/alan/web/prod/nginxsec
alan     20882 20881  0 11:18 ?        00:00:00 nginx: worker process
alan     20895  1454  0 11:19 ?        00:00:00 nginx: master process nginx
alan     20896 20895  0 11:19 ?        00:00:00 nginx: worker process

使用 greppgrep 将显示 PID 数字,但我们可能无法辨别哪个实例是哪个。

alan@workstation:~$ pgrep nginx
20881
20882
20895
20896

pidof 命令可用于确定每个特定 Nginx 实例的 PID。

alan@workstation:~$ pidof /home/alan/web/prod/nginxsec/sbin/nginx
20882 20881

alan@workstation:~$ pidof /home/alan/web/prod/nginx/sbin/nginx
20896 20895

TOP

top 命令已经有很久的历史了,对于查看运行进程的细节和快速识别内存消耗等问题是非常有用的。其默认视图如下所示。

top - 11:56:28 up 1 day, 13:37,  1 user,  load average: 0.09, 0.04, 0.03
Tasks: 292 total,   3 running, 225 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.2 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 16387132 total, 10854648 free,  1859036 used,  3673448 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 14176540 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
17270 alan      20   0 3930764 247288  98992 R   0.7  1.5   5:58.22 gnome-shell
20496 alan      20   0  816144  45416  29844 S   0.5  0.3   0:22.16 gnome-terminal-
21110 alan      20   0   41940   3988   3188 R   0.1  0.0   0:00.17 top
    1 root      20   0  225564   9416   6768 S   0.0  0.1   0:10.72 systemd
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.01 kthreadd
    4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H
    6 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 mm_percpu_wq
    7 root      20   0       0      0      0 S   0.0  0.0   0:00.08 ksoftirqd/0

可以通过键入字母 s 和您喜欢的更新秒数来更改更新间隔。为了更容易监控我们的示例 Nginx 进程,我们可以使用 -p 选项并传递 PID 来调用 top。这个输出要干净得多。

alan@workstation:~$ top -p20881 -p20882 -p20895 -p20896

Tasks:   4 total,   0 running,   4 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.8 us,  1.3 sy,  0.0 ni, 95.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 16387132 total, 10856008 free,  1857648 used,  3673476 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 14177928 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
20881 alan      20   0   12016    348      0 S   0.0  0.0   0:00.00 nginx
20882 alan      20   0   12460   1644    932 S   0.0  0.0   0:00.00 nginx
20895 alan      20   0   12016    352      0 S   0.0  0.0   0:00.00 nginx
20896 alan      20   0   12460   1628    912 S   0.0  0.0   0:00.00 nginx

在管理进程,特别是终止进程时,正确确定 PID 是非常重要。此外,如果以这种方式使用 top,每当这些进程中的一个停止或一个新进程开始时,top 都需要被告知有新的进程。

终止进程

KILL

有趣的是,没有 stop 命令。在 Linux 中,有 kill 命令。kill 用于向进程发送信号。最常用的信号是“终止”(SIGTERM)或“杀死”(SIGKILL)。然而,还有更多。下面是一些例子。完整的列表可以用 kill -L 显示。

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM

注意第 9 号信号是 SIGKILL,通常,我们会发出比如 kill -9 20896 这样的命令。默认信号是 15,这是 SIGTERM。请记住,许多应用程序都有自己的停止方法。Nginx 使用 -s 选项传递信号,如 stopreload。通常,我更喜欢使用应用程序的特定方法来停止操作。然而,我将演示用 kill 命令来停止 Nginx 进程 20896,然后用 pgrep 确认它已经停止。PID 20896 就不再出现。

alan@workstation:~$ kill -9 20896
 
alan@workstation:~$ pgrep nginx
20881
20882
20895
22123

PKILL

命令 pkill 类似于 pgrep,因为它可以按名称搜索。这意味着在使用 pkill 时必须非常小心。在我的 Nginx 示例中,如果我只想杀死一个 Nginx 实例,我可能不会选择使用它。我可以将 Nginx 选项 -s stop 传递给特定的实例来消除它,或者我需要使用 grep 来过滤整个 ps 输出。

/home/alan/web/prod/nginx/sbin/nginx -s stop
/home/alan/web/prod/nginxsec/sbin/nginx -s stop

如果我想使用 pkill,我可以包括 -f 选项,让 pkill 过滤整个命令行参数。这当然也适用于 pgrep。所以,在执行 pkill -f 之前,首先我可以用 pgrep -a 确认一下。

alan@workstation:~$ pgrep -a nginx
20881 nginx: master process ./nginx -p /home/alan/web/prod/nginxsec
20882 nginx: worker process
20895 nginx: master process nginx
20896 nginx: worker process

我也可以用 pgrep -f 缩小我的结果。pkill 使用相同参数会停止该进程。

alan@workstation:~$ pgrep -f nginxsec
20881
                                           
alan@workstation:~$ pkill -f nginxsec

pgrep(尤其是 pkill)要记住的关键点是,您必须始终确保搜索结果准确性,这样您就不会无意中影响到错误的进程。

大多数这些命令都有许多命令行选项,所以我总是建议阅读每一个命令的 man 手册页。虽然大多数这些命令都存在于 Linux、Solaris 和 BSD 等平台上,但也有一些不同之处。在命令行工作或编写脚本时,始终测试并随时准备根据需要进行更正。


via: https://opensource.com/article/18/9/linux-commands-process-management

作者:Alan Formy-Duval 选题:lujun9972 译者:heguangzhi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

作为一名博客作者,我收藏了很多博客、网站和论坛用来寻找 Linux 和 Unix 相关的内容。有时候,我在浏览器中开启了非常多的标签页,导致操作系统会无响应好几分钟。我不能移动我的鼠标,也不能杀掉一个进程或关闭任何开启的标签页。在这种情况下,我别无选择,只能强制重启系统。当然我也用了 OneTab (LCTT 译注:OneTab 是一个 Chrome 的 Extension,可以将标签页转化成一个列表保存。)和 Greate Suspender (LCTT 译注:Great Suspender 是一个 Chrome 的 Extension, 可以自动冻结标签页)这样浏览器拓展,但它们在这里也起不到太大的作用。 我经常耗尽我的内存。而这就是 Early OOM 起作用的时候了。在情况严重时,它会杀掉一个未响应系统中的内存消耗最大的进程。Early OOM 每秒会检测可用内存和空余交换区 10 次,一旦两者都低于 10%,它就会把最大的进程杀死。

为什么用 Early OOM?为什么不用系统内置的 OOM killer?

在继续讨论下去之前,我想先简短的介绍下 OOM killer,也就是 Out Of Memory killer。OOM killer 是一个由内核在可用内存非常低的时候使用的进程。它的主要任务是不断的杀死进程,直到释放出足够的内存,使内核正在运行的其它进程能顺利运行。OOM killer 会找到系统中最不重要并且能释放出最多内存的进程,然后杀掉他们。在 /proc 目录下的 pid 目录中,我们可以看到每个进程的 oom_score

示例:

$ cat /proc/10299/oom_score
1

一个进程的 oom_score 的值越高,这个进程越有可能在系统内存耗尽的时候被 OOM killer 杀死。

Early OOM 的开发者表示,相对于内置的 OOM killer,Early OOM 有一个很大的优点。就像我之前说的那样,OOM killer 会杀掉 oom_score 最高的进程,而这也导致 Chrome 浏览器总是会成为第一个被杀死的进程。为了避免这种情况发生,Early OOM 使用 /proc/*/status 而不是 echo f > /proc/sysrq-trigger(LCTT 译注:这条命令会调用 OOM killer 杀死进程)。开发者还表示,手动触发 OOM killer 在最新版本的 Linux 内核中很可能不会起作用。

安装 Early OOM

Early OOM 在 AUR(Arch User Repository)中可以找到,所以你可以在 Arch 和它的衍生版本中使用任何 AUR 工具安装它。

使用 Pacaur

pacaur -S earlyoom

使用 Packer

packer -S earlyoom

使用 Yaourt

yaourt -S earlyoom

启用并启动 Early OOM 守护进程:

sudo systemctl enable earlyoom
sudo systemctl start earlyoom

在其它的 Linux 发行版中,可以按如下方法编译安装它:

git clone https://github.com/rfjakob/earlyoom.git
cd earlyoom
make
sudo make install

Early OOM - 杀掉无响应 Linux 系统中的最大的进程

运行如下命令启动 Early OOM:

earlyoom

如果是通过编译源代码安装的, 运行如下命令启动 Early OOM:

./earlyoom

示例输出:

earlyoom 0.12
mem total: 3863 MiB, min: 386 MiB (10 %)
swap total: 2047 MiB, min: 204 MiB (10 %)
mem avail: 1770 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1772 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1772 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1771 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1773 MiB (45 %), swap free: 2047 MiB (99 %)
mem avail: 1784 MiB (46 %), swap free: 2047 MiB (99 %)
[...]

就像你在上面的输出中可以看到的,Early OOM 将会显示你有多少内存和交换区,以及有多少可用的内存和交换区。记住它会一直保持运行,直到你按下 CTRL+C

如果可用的内存和交换区大小都低于 10%,Early OOM 将会自动杀死最大的进程,直到系统有足够的内存可以流畅的运行。你也可以根据你的需求配置最小百分比值。

设置最小的可用内存百分比,运行:

earlyoom -m <PERCENT_HERE>

设置最小可用交换区百分比, 运行:

earlyoom -s <PERCENT_HERE>

在帮助部分,可以看到更多详细信息:

$ earlyoom -h
earlyoom 0.12
Usage: earlyoom [OPTION]...

 -m PERCENT set available memory minimum to PERCENT of total (default 10 %)
 -s PERCENT set free swap minimum to PERCENT of total (default 10 %)
 -M SIZE set available memory minimum to SIZE KiB
 -S SIZE set free swap minimum to SIZE KiB
 -k use kernel oom killer instead of own user-space implementation
 -i user-space oom killer should ignore positive oom_score_adj values
 -d enable debugging messages
 -v print version information and exit
 -r INTERVAL memory report interval in seconds (default 1), set to 0 to
 disable completely
 -p set niceness of earlyoom to -20 and oom_score_adj to -1000
 -h this help text

现在,你再也不用担心内存消耗最高的进程了。希望这能给你帮助。更多的好内容将会到来,敬请期待。

谢谢!


via: https://www.ostechnix.com/kill-largest-process-unresponsive-linux-system/

作者:Aditya Goturu 译者:cizezsy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

由于复刻了 mon 项目到 etbemon 中,我花了一些时间做监视脚本。事实上监视一些事情通常很容易,但是决定监视什么才是困难的部分。进程监视脚本 ps.monitor 是我重新设计过的一个。

对于进程监视我有一些思路。如果你对进程监视如何做的更好有任何建议,请通过评论区告诉我。

给不使用 mon 的人介绍一下,如果一切 OK 该监视脚本就返回 0,而如果有问题它会返回 1,并使用标准输出显示错误信息。虽然我并不知道有谁将 mon 脚本挂进一个不同的监视系统中,但是,那样做其实很容易实现。我计划去做的一件事情就是,将来实现 mon 和其它的监视系统如 Nagios 之间的互操作性。

基本监视

ps.monitor tor:1-1 master:1-2 auditd:1-1 cron:1-5 rsyslogd:1-1 dbus-daemon:1- sshd:1- watchdog:1-2

我现在计划重写该进程监视脚本的某些部分。现在的功能是在命令行上列出进程名字,它包含了要监视的进程的最小和最大实例数量。上面的示例是一个监视的配置。在这里有一些限制,在这个实例中的 master 进程指的是 Postfix 的主进程,但是其它的守护进程使用了相同的进程名(这是那些错误的名字之一,因为它太直白了)。一个显而易见的解决方案是,给一个指定完整路径的选项,这样,那个 /usr/lib/postfix/sbin/master 就可以与其它命名为 master 的程序区分开了。

下一个问题是那些可能以多个用户身份运行的进程。比如 sshd,它有一个以 root 身份运行的单独的进程去接受新的连接请求,以及在每个登入用户的 UID 下运行的进程。因此,作为 root 用户运行的 sshd 进程的数量将比 root 登录会话的数量大 1。这意味着如果一个系统管理员直接以 root 身份通过 ssh 登入系统(这是有争议的,但它不是本文的主题—— 只是有些人需要这样做,所以我们必须支持这种情形),然后 master 进程崩溃了(或者系统管理员意外或者故意杀死了它),这时对于该进程丢失并不会产生警报。当然正确的做法是监视 22 号端口,查找字符串 SSH-2.0-OpenSSH_。有时候,守护进程的多个实例运行在需要单独监视的不同 UID 下面。因此,我们需要通过 UID 监视进程的能力。

在许多情形中,进程监视可以被替换为对服务端口的监视。因此,如果在 25 号端口上监视,那么有可能意味着,Postfix 的 master 在运行着,不用去理会其它的 master 进程。但是对于我而言,我可以在方便地进行多个监视,如果我得到一个关于无法向一个服务器发送邮件的 Jabber 消息,我可以通过这个来自服务器的 Jabber 消息断定 master 没有运行,而不需要挨个查找才能发现问题所在。

SE Linux

我想要的一个功能就是,监视进程的 SE Linux 上下文,就像监视 UID 一样。虽然我对为其它安全系统编写一个测试不感兴趣,但是,我很乐意将别人写好的代码包含进去。因此,不管我做什么,都希望它能与多个安全系统一起灵活地工作。

短暂进程

大多数守护进程在进程启动期间都有一个相同名字的 次级进程 second process 。这意味着如果你为了精确地监视一个进程的一个实例,当 logrotate 或者类似的守护进程重启时,你或许会收到一个警报说有两个进程运行。如果在重启期间,恰好在一个错误的时间进行检查,你也或许会收到一个警报说,有 0 个实例。我现在处理这种情况的方法是,在与 alertafter 2 指令一起的次级进程失败事件之前我的服务器不发出警报。当监视处于一个失败的状态时,failure_interval 指令允许指定检查的时间间隔,将其设置为一个较低值时,意味着在等待一个次级进程失败结果时并不会使提示延迟太多。

为处理这种情况,我考虑让 ps.monitor 脚本在一个指定的延迟后再次进行自动检查。我认为使用一个单个参数的监视脚本来解决这个问题比起使用两个配置指令的 mon 要好一些。

CPU 使用

mon 现在有一个 loadavg.monitor 脚本,它用于检查平均负载。但是它并不能捕获一个单个进程使用了太多的 CPU 时间而没有使系统平均负载上升的情况。同样,也没有捕获一个渴望获得 CPU 的进程进入沉默(例如,SETI at Home 停止运行)(LCTT 译注:SETI,由加州大学伯克利分校创建的一项利用全球的联网计算机的空闲计算资源来搜寻地外文明的科学实验计划),而其它的进程进入一个无限循环状态的情况。解决这种问题的一个方法是,让 ps.monitor 脚本也配置另外的一个选项去监视 CPU 的使用,但是这也可能会让人产生迷惑。另外的选择是,使用一个独立的脚本,它用来报警任何在它的生命周期或者最后几秒中,使用 CPU 时间超过指定百分比的进程,除非它在一个豁免这种检查的进程或用户的白名单中。或者每个普通用户都应该豁免这种检查,因为你压根就不知道他们什么时候运行一个文件压缩程序。也应该有一个包含排除的守护进程(像 BOINC)和系统进程(像 gzip,有几个定时任务会运行它)的简短列表。

对例外的监视

一个常见的编程错误是在 setgid() 之前调用 setuid(),这意味着那个程序没有权限去调用 setgid()。如果没有检查返回代码(而犯这种低级错误的人往往不会去检查返回代码),那么进程会保持较高的权限。检查以 GID 0 而不是 UID 0 运行的进程是很方便的。顺利说一下,对一个 Debian/Testing 工作站运行的一个快速检查显示,一个使用 GID 0 的进程并没有获得较高的权限,但是可以使用一个 chmod 770 命令去改变它。

在一个 SE Linux 系统上,应该只有一个进程与 init_t 域一起运行。目前在运行守护进程(比如,mysqld 和 tor)的 Debian Stretch 系统中,并不会发生策略与守护进程服务文件所请求的 systemd 的最新功能不匹配的情况。这样的问题将会不断发生,我们需要对它进行自动化测试。

对配置错误的自动测试可能会影响系统安全,这是一个很大的问题,我将来或许写一篇关于这方面的单独的博客文章。


via: https://etbe.coker.com.au/2017/09/28/process-monitoring/

作者:Andrew 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出