v>

linux ps命令


二.查看系统进程的状态信息

回到顶部
思考如下问题: 1.linux系统下运行着非常多的进程,如果系统资源非常紧张,如何找出做消耗系统资源的进程? 2.如果某个进程发生了错误,怎么找到这个错误进程并将其从linux系统中删除呢? 3.你可能希望某项工作能够快点运行完毕,如何让进程可以优先运行呢?
上面这些问题都涉及到进程的管理问题。
一个称职的linux系统管理员,必须要熟悉进程的管理流程才行,否则当系统发生问题时,还真的束手无策了! 下面我们就来详细了解系统的进程管理!
有很多命令可以查看系统中运行进程的状态信息,这些工具有ps、pstree和top等。其中ps和pstree可以静态的显示系统进程状态, 而top可以实时的动态显示系统进程的状态信息。
既然进程这么重要,那么我们如何查阅系统上面正在运作当中的进程呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅进程树之间的关系喔!

1.ps打印当前时刻进程的运行状态

回到顶部
ps命令常用的命令格式如下所示:
[root@initroot ~]# ps aux    #观察系统所有的进程数据
[root@initroot ~]# ps -lA    #也是能够观察所有系统的数据
[root@initroot ~]# ps axjf   #连同部分进程树状态
选项与参数:
-A :显示系统中所有的进程,与-e具有同样的效用;
-a :显示具有控制终端(terminal)的进程;
-u :有效用户(effective user)相关的process;
x :通常与a选项一起使用,可列出进程的较完整信息。
输出格式规划:
l :显示进程的详细信息;
j :工作的格式(jobs format);
-f :做一个更为完整的输出。
ps默认只列出当前bash进程及其相关进程的信息,相关进程大多是bash的子进程。-l选项可以列出更加详细的进程信息。 更为常用的是显示系统中所有的进程状态信息ps aux.
只列出当前bash进程和相关进程信息:
[peter@initroot ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  2062  2056  0  80   0 -  6277 wait   pts/0    00:00:00 bash
4 R  1000  5109  2062  0  80   0 -  7663 -      pts/0    00:00:00 ps
上述输出的各字段含义如下所示:
F:进程标志(process flags),常见号码有:
4表示此进程的权限为root;
1则表示此子进程仅进行复制(fork)而没有实际执行(exec)。
S:进程的状态(STAT),主要的状态有:
R (Running):该程序正在运作中;
S (Sleep):该程序目前正处在睡眠状态(idle),但可以被唤醒(signal)。
D :不可被唤醒的睡眠状态,通常进程可能在等待I/O
T :停止状态(stop),可能是在工作控制(背景暂停)或被追踪(traced)状态;
Z :僵尸(Zombie)状态,进程已经终止,但是尸体还留在内存中,需要父进程来收尸。
UID:进程的用户ID;
PID:进程ID;
PPID:进程的父进程ID;
C:CPU使用率,单位为百分比;
PRI/NI: Priority/Nice的缩写,表示此进程被CPU所执行的优先级,数值越小代表该进程越快被CPU执行。详细的 PRI 与 NI 将在下一小节说明。
ADDR/SZ/WCHAN:都与内存有关,ADDR是kernel function,指出该进程在内存的哪个部分, 如果是个running的进程,一般就会显示- / SZ 代表此进程用掉多少内存 / WCHAN 表示目前进程是否运作中,同样的, 若为 - 表示正在运作中。
TTY:登录用户的控制终端,若为远程登录则使用动态终端接口(pts/n);
TIME:使用掉的CPU时间,注意,是此进程实际花费CPU运作的时间,而不是系统时间;
CMD:command的缩写,触发此进程的命令。
bash进程的UID为0,这是普通用户peter的UID,也就是说这条进程是用户peter的进程。如果当前用户root,并且进程是由root触发的,那么进程的UID就是0了。 bash进程的状态为S睡眠(sleep), 之所以为睡眠因为他触发了ps(状态为run) 之故。PID为2062,,优先级为80, bash进程的终端接口为 pts/0 ,运行状态为等待(wait)
上面的输出可以看出当前bash环境只有两个进程,bash和ps,由于我们是在当前bash环境下执行的ps命令,所以理所当然ps进程就是bash进程的子进程了。 我们看到ps进程的PPID为2062,这正是bash进程的PID。也可通过pstree命令观察ps和bash进程的父子关系。
注意ps命令列出的是ps命令执行的那个时刻点的进程信息。 其实ps命令执行的非常快,在显示完上述信息后,这个ps进程就已经结束了。 如果我们再次执行ps -l,会发现ps进程的PID已经不是5109了,说明这是一个新的ps进程,而刚才的ps进程在输出信息后就已经结束退出了。 因为我们是在同一个bash下执行的ps命令,所以产生的ps进程的父进程都是一样的,就是当前的bash进程了,所以你会发现不管执行多少个ps -l命令, ps进程的PID一直在变化,而PPID一直没有变化。
ps -l只列出了两个进程,没什么意思啊,没啥感觉啊。我们继续作一下,干一票大的。当前登录用户是peter,我们通过su -将用户切换为root, 然后在命令行下执行一个wget下载任务,下载linux内核文件,然后再执行ps -l观察进程信息:
[peter@initroot ~]# su -
Password: 
[root@initroot:~]# nohup wget -c https://git.kernel.org/torvalds/t/linux-5.5-rc6.tar.gz > /dev/null 2>&1 &
[1] 5097
[root@initroot ~]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  4911  2062  0  80   0 - 21370 wait   pts/0    00:00:00 su
4 S     0  4924  4911  0  80   0 -  6100 wait   pts/0    00:00:00 bash
0 S     0  5097  4924  0  80   0 - 10615 poll_s pts/0    00:00:00 wget
4 R     0  5098  4924  0  80   0 -  7663 -      pts/0    00:00:00 ps
我们通过su -切换到root用户,然后在后台执行了一个wget下载任务,关于这条下载命令我们会在后面详细解释。 再次通过ps -l命令观察就会发现多了几个进程,仔细观察会发现bash进程的PID发生了变化,刚才是2062,现在怎么变成4924了?而su进程的PPID是2062. 我们通过每个进程的PID和PPID仔细梳理就会发现这些进程之间的父子关系为:bash(2062)--su(4911)--bash(4924)--wget(5097)、ps(5098). 原来这是两个不同的bash,也就是说我们通过su命令进入了另一个bash环境,这两个bash进程是爷孙关系。 这里注意我们通过wget下载的文件非常大,所以wget进程一时半会儿还不会结束,假如这个时候我用exit命令退出了当前的bash(4924)环境回到刚才的bash(2062)环境, 那么su(4911)进程及其子进程bash(4924)就会结束退出,这对于wget(5097)进程是一个极度悲伤的事情,因为老爸bash(4924)进程和老爹su(4911)进程都相继去世了。 而兄弟ps(5098)进程也早早的结束了自己的使命归天了。其实上面如果我们在执行下载命令的时候不加上nohup,那么wget(5097)进程也会因为悲伤过度而去世。 而加上nohup后,wget(5097)进程就可以坚强的活了下来,但是因为父进程已经去世了,所以wget(5097)进程就变成孤儿进程。
[root@initroot ~]# exit
[peter@initroot ~]# su -
Password: 
[root@initroot ~]:~# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S     0  5097  1174  3  80   0 - 10648 wait_w pts/0    00:00:07 wget
4 S     0  5112  2062  0  80   0 - 21370 wait   pts/0    00:00:00 su
4 S     0  5113  5112  0  80   0 -  6100 wait   pts/0    00:00:00 bash
4 R     0  5126  5113  0  80   0 -  7663 -      pts/0    00:00:00 ps
我们发现su(5112)、bash(5113)、ps(5126)已经不是刚才的su(4911)、bash(4924)、ps(5098),对于wget(5097)进程来说,真是物是人非啊。 但是奇怪的是,wget(5097)进程的PPID居然变成1174了?父进程不是去世了吗?怎么又有PPID了呢? 原来我们可怜的wget(5097)进程被进程ID为1174的进程收养了!通过ps aux命令我们找到PID为1174的进程,原来是/lib/systemd/systemd进程, 也就是说系统中的孤儿进程会被/lib/systemd/systemd进程收养。以前的linux系统,孤儿进程会被1号进程init收养。 ps默认只能列出和当前bash进程相关的进程,使用ps aux可以列出系统中目前在内存中的所有进程信息:
[root@initroot ~]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2 191024  2588 ?        Ss    2019   4:26 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root         2  0.0  0.0      0     0 ?        S     2019   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S     2019   1:04 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<    2019   0:00 [kworker/0:0H]
root         7  0.0  0.0      0     0 ?        S     2019   0:00 [migration/0]
root         8  0.0  0.0      0     0 ?        S     2019   0:00 [rcu_bh]
root         9  0.0  0.0      0     0 ?        R     2019  23:00 [rcu_sched]
root        10  0.0  0.0      0     0 ?        S<    2019   0:00 [lru-add-drain]
root        11  0.0  0.0      0     0 ?        S     2019   0:26 [watchdog/0]
root        13  0.0  0.0      0     0 ?        S     2019   0:00 [kdevtmpfs]
root        14  0.0  0.0      0     0 ?        S<    2019   0:00 [netns]
root        15  0.0  0.0      0     0 ?        S     2019   0:01 [khungtaskd]
root        16  0.0  0.0      0     0 ?        S<    2019   0:00 [writeback]
root        17  0.0  0.0      0     0 ?        S<    2019   0:00 [kintegrityd]
root        18  0.0  0.0      0     0 ?        S<    2019   0:00 [bioset]
root        19  0.0  0.0      0     0 ?        S<    2019   0:00 [bioset]
root        20  0.0  0.0      0     0 ?        S<    2019   0:00 [bioset]
root        21  0.0  0.0      0     0 ?        S<    2019   0:00 [kblockd]
root        22  0.0  0.0      0     0 ?        S<    2019   0:00 [md]
root        23  0.0  0.0      0     0 ?        S<    2019   0:00 [edac-poller]
root        24  0.0  0.0      0     0 ?        S<    2019   0:00 [watchdogd]
root        30  0.0  0.0      0     0 ?        S     2019   2:17 [kswapd0]
root        31  0.0  0.0      0     0 ?        SN    2019   0:00 [ksmd]
root        32  0.0  0.0      0     0 ?        SN    2019   0:11 [khugepaged]
root        33  0.0  0.0      0     0 ?        S<    2019   0:00 [crypto]
root        41  0.0  0.0      0     0 ?        S<    2019   0:00 [kthrotld]
root        43  0.0  0.0      0     0 ?        S<    2019   0:00 [kmpath_rdacd]
root        44  0.0  0.0      0     0 ?        S<    2019   0:00 [kaluad]
root        45  0.0  0.0      0     0 ?        S<    2019   0:00 [kpsmoused]
root        46  0.0  0.0      0     0 ?        S<    2019   0:00 [ipv6_addrconf]
root        59  0.0  0.0      0     0 ?        S<    2019   0:00 [deferwq]
root       102  0.0  0.0      0     0 ?        S     2019   0:00 [kauditd]
root       236  0.0  0.0      0     0 ?        S<    2019   0:00 [ata_sff]
root       247  0.0  0.0      0     0 ?        S     2019   0:00 [scsi_eh_0]
root       248  0.0  0.0      0     0 ?        S<    2019   0:00 [scsi_tmf_0]
root       249  0.0  0.0      0     0 ?        S     2019   0:00 [scsi_eh_1]
root       250  0.0  0.0      0     0 ?        S<    2019   0:00 [scsi_tmf_1]
root       255  0.0  0.0      0     0 ?        S<    2019   0:00 [ttm_swap]
root       261  0.0  0.0      0     0 ?        S<    2019   1:43 [kworker/0:1H]
root       271  0.0  0.0      0     0 ?        S     2019   2:11 [jbd2/vda1-8]
root       272  0.0  0.0      0     0 ?        S<    2019   0:00 [ext4-rsv-conver]
root       339  0.0  0.3  47324  3356 ?        Ss    2019   0:33 /usr/lib/systemd/systemd-journald
root       357  0.0  0.0  44484   908 ?        Ss    2019   0:00 /usr/lib/systemd/systemd-udevd
root       458  0.0  0.0      0     0 ?        S<    2019   0:00 [nfit]
root       460  0.0  0.0  55520   856 ?        S<sl  2019   0:08 /sbin/auditd
dbus       487  0.0  0.1  58108  1272 ?        Ss    2019   3:09 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
ntp        492  0.0  0.1  47276  1412 ?        Ss    2019   0:32 /usr/sbin/ntpd -u ntp:ntp -g
polkitd    496  0.0  1.0 612328 10392 ?        Ssl   2019   0:20 /usr/lib/polkit-1/polkitd --no-debug
root       497  0.0  0.1  26612  1372 ?        Ss    2019   1:21 /usr/lib/systemd/systemd-logind
root       501  0.0  0.1 126284  1088 ?        Ss    2019   0:14 /usr/sbin/crond -n
root       506  0.0  0.0  25904   312 ?        Ss    2019   0:00 /usr/sbin/atd -f
root       530  0.0  0.0 110104   364 ttyS0    Ss+   2019   0:00 /sbin/agetty --keep-baud 115200,38400,9600 ttyS0 vt220
root       531  0.0  0.0 110104   372 tty1     Ss+   2019   0:00 /sbin/agetty --noclear tty1 linux
root       717  0.0  0.2 107464  2048 ?        Ss    2019   0:00 /sbin/dhclient -1 -q -lf /var/lib/dhclient/dhclient--eth0.lease -pf /var/run/dhclient-eth0.pid -H izm5e94e7bypr5rhnhbvq9z eth0
root       782  0.0  1.1 573932 11976 ?        Ssl   2019  12:54 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
root       791  0.0  0.5 352880  5568 ?        Ssl   2019   5:32 /usr/sbin/rsyslogd -n
root       797  0.0  0.3  41072  3200 ?        Ssl   2019  49:59 /usr/sbin/aliyun-service
mysql      927  0.0  0.0 113308   584 ?        Ss    2019   0:00 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
mysql     1193  0.0 11.6 1189784 118372 ?      Sl    2019  60:40 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mariadb/mariadb.log --pid
root      1242  0.0  0.1 112864  1560 ?        Ss    2019   0:01 /usr/sbin/sshd -D
root      2530  0.0  0.2  32528  2232 ?        S<sl  2019  34:34 /usr/local/aegis/aegis_update/AliYunDunUpdate
root      2586  2.8  1.7 139372 17268 ?        S<sl  2019 2508:22 /usr/local/aegis/aegis_client/aegis_10_75/AliYunDun
apache    3290  0.0  1.8 401376 19016 ?        S     2019   1:33 php-fpm: pool www
...部分省略...
root     10351  0.0  0.5 390312  5404 ?        Ss    2019   3:10 php-fpm: master process (/etc/php-fpm.conf)
...部分省略...
root     10373  0.0  0.2 125876  2320 ?        Ss    2019   0:00 nginx: master process /usr/sbin/nginx
nginx    10374  0.0  0.7 129004  7620 ?        S     2019   5:18 nginx: worker process
...部分省略...
root     15615  0.0  0.0      0     0 ?        S    Jan07   0:00 [kworker/u2:1]
root     15728  0.0  2.3 734928 24344 ?        Sl   Jan07   0:00 npm
root     15741  0.0  7.2 872332 73268 ?        Sl   Jan07   1:47 node /home/wwwroot/default/kblog/node_modules/.bin/nuxt start
apache   27911  0.0  1.9 403656 19652 ?        S     2019   2:48 php-fpm: pool www
apache   28122  0.0  1.9 403640 19444 ?        S     2019   2:48 php-fpm: pool www
root     30895  0.0  0.0      0     0 ?        S    08:40   0:00 [kworker/u2:2]
root     31200  0.0  0.5 157388  6052 ?        Ss   10:49   0:00 sshd: root@notty
root     31202  0.0  0.3  72336  3064 ?        Ss   10:49   0:00 /usr/libexec/openssh/sftp-server
root     31547  0.0  0.0      0     0 ?        S    12:30   0:00 [kworker/0:0]
root     31589  0.0  0.5 157404  6052 ?        Ss   12:43   0:00 sshd: root@notty
root     31591  0.0  0.2  72268  2940 ?        Ss   12:43   0:00 /usr/libexec/openssh/sftp-server
root     31611  0.0  0.0      0     0 ?        R    13:00   0:00 [kworker/0:1]
root     31624  0.2  0.5 157256  6020 ?        Ss   13:07   0:00 sshd: root@pts/0
root     31626  0.0  0.2 115572  2128 pts/0    Ss   13:07   0:00 -bash
root     31641  0.0  0.1 155360  1932 pts/0    R+   13:07   0:00 ps aux
ps aux输出的各字段和ps -l的输出有所不同,pa aux输出的各字段的意义为:
USER:该 process 的用户帐号名
PID :该 process 的进程PID;
%CPU:该 process 使用掉的CPU资源百分比;
%MEM:该 process 所占用的物理内存百分比;
VSZ :该 process 使用掉的虚拟内存量 (Kbytes)
RSS :该 process 占用的固定的内存量 (Kbytes)
TTY :该 process 是在那个终端机上面运作,若与终端机无关则显示?,另外, tty1-tty6 是本机上面的登入者进程,若为 pts/0 等等的,则表示为由网络连接进主机的进程。
STAT:该进程目前的状态,状态显示与 ps -l 的 S 旗标相同 (R/S/T/Z)
START:该 process 被触发启动的时间;
TIME :该 process 实际使用 CPU 运作的时间。
COMMAND:该进程的实际指令为何?
一般来说ps aux会按照PID的顺序来排序显示。我们以为上面的bash进程为例说明,该进程的执行用户为root,进程PID为31626,占用了0.2%的内存容百分比,状态为休眠(S), 该进程启动的时间为13:07,如果进程启动运行的时间很久,就不会列出实际的启动时间。这个bash是我刚刚通过ssh远程连接而启动的bash进程,控制终端为pts/0。
使用ps -lA列出所有的进程信息
[root@initroot ~]# ps -lA
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0     1     0  0  80   0 - 47756 ep_pol ?        00:04:26 systemd
1 S     0     2     0  0  80   0 -     0 kthrea ?        00:00:00 kthreadd
1 S     0     3     2  0  80   0 -     0 smpboo ?        00:01:04 ksoftirqd/0
...(省略)...
每个字段与 ps -l 的输出情况相同,但显示的进程则包括系统所有的进程。
使用ps axjf以树状结构显示进程:
[root@initroot ~]# ps axjf
PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
   0     2     0     0 ?           -1 S        0   0:00 [kthreadd]
   2     3     0     0 ?           -1 S        0   1:04  \_ [ksoftirqd/0]
   2     5     0     0 ?           -1 S<       0   0:00  \_ [kworker/0:0H]
   2     7     0     0 ?           -1 S        0   0:00  \_ [migration/0]
   2     8     0     0 ?           -1 S        0   0:00  \_ [rcu_bh]
   2     9     0     0 ?           -1 R        0  23:00  \_ [rcu_sched]
   ...(省略)...
1242 31200 31200 31200 ?           -1 Ss       0   0:00  \_ sshd: root@notty
31200 31202 31202 31202 ?           -1 Ss       0   0:00  |   \_ /usr/libexec/openssh/sftp-server
1242 31589 31589 31589 ?           -1 Ss       0   0:00  \_ sshd: root@notty
31589 31591 31591 31591 ?           -1 Ss       0   0:00  |   \_ /usr/libexec/openssh/sftp-server
1242 31624 31624 31624 ?           -1 Ss       0   0:00  \_ sshd: root@pts/0
31624 31626 31626 31626 pts/0    31675 Ss       0   0:00      \_ -bash
31626 31675 31675 31626 pts/0    31675 R+       0   0:00          \_ ps axjf
...(省略)...
很多时候我们都是通过ssh远程登录的方式取得bash环境的,通过上面的进程关系也可以看出来。 还可以使用pstree命令来显示进程之间的父子关系。其他各字段的意义可以man ps
找出与cron与rsyslog这两个服务进程的PID:
[root@initroot ~]# ps aux | egrep '(cron|rsyslog)'
root       501  0.0  0.1 126284  1088 ?        Ss    2019   0:14 /usr/sbin/crond -n
root       791  0.0  0.5 352880  5568 ?        Ssl   2019   5:32 /usr/sbin/rsyslogd -n
root     31693  0.0  0.1 112708  1052 pts/0    R+   13:28   0:00 grep -E --color=auto (cron|rsyslog)
可以看出crond进程的pid为501, rsyslogd进程的pid为791。 僵尸(zombie)进程是什么? 通常,造成僵尸进程的成因是因为该进程应该已经执行完毕,或者是因故应该要终止了, 但是该进程的父进程却无法完整的将该进程结束掉,而造成那个进程一直存在内存当中。
如果你发现在某个进程的 CMD 后面还接上<defunct> 时,就代表该进程是僵尸进程啦,例如:
apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd <defunct>
当系统不稳定的时候就容易造成所谓的僵尸进程,可能是因为程序写的不好啦,或者是使用者的操作习惯不良等等所造成。 如果你发现系统中很多僵尸进程时,记得啊!要找出该进程的父进程, 然后好好的做个追踪,好好的进行主机的环境优化啊! 看看有什么地方需要改善的,不要只是直接将他kill掉而已呢!不然的话,万一他一直产生,那可就麻烦了!
事实上,通常僵尸进程都已经无法控管,而直接是交给systemd进程来负责了,偏偏 systemd是系统第一支执行的程序, 他是所有程序的父程序! 我们无法杀掉该程序的 (杀掉他,系统就死掉了!),所以啰,如果产生僵尸进程, 而系统过一阵子还没有办法透过核心非经常性的特殊处理来将该进程删除时,那你只好透过reboot的方式来将该进程抹去了!

ps命令查看进程信息

ps
ps -aux
ps -elf

七.与进程相关的其他命令

回到顶部
还有一些与进程有关的命令可以值得参考与应用

1.fuser找出正在使用某个文件的进程

回到顶部
当你在删除某个文件时,这个文件却被某个进程占用着,这时候是不能删除的。那么怎么找到占用该文件的进程呢? 或者你用umount卸载某个文件系,却出现了device is busy的提示,这表明文件系统正在被某个进程使用。 这时候就可以使用fuser命令了。fuser语法有点像这样:
[root@initroot ~]# fuser [-umv] [-k [i] [-signal]] file/dir
选项与参数:
-u :除了进程的PID之外,同时列出该进程的拥有者;
-m :该文件所在的文件系统,后面接的那个文件名会主动的上提到该文件系统的最顶层,对umount不成功很有效!
-v :可以列出每个文件与进程还有指令的完整相关性!
-k :向找到的进程发送信号,信号由-signal指定,如果没有指定信号名或者信号编号,默认为SIGKILL信号;
-i :用户交互模式,必须与-k配合,在删除进程之前会先询问使用者!
-signal:例如 -1 -15 等等,若不加的话,默认是 SIGKILL (-9) 啰!
范例一:找出目前所在目录的使用 PID/所属账号/权限 为何? 看看有哪些进程正在使用当前工作目录:
[root@initroot ~]# fuser -uv .
                     USER        PID ACCESS COMMAND
/root:               root       6632 ..c.. (root)bash

正在使用当前工作目录的进程为bash进程,进程pid为6632,该进程属于root用户。比较有趣的是ACCESS字段,该字段代表的意义为:
c :此进程在当前的目录下(非次目录);
e :可被触发为执行状态;
f :是一个被开启的文件;
r :代表顶层目录(root directory);
F :该文件被开启了,不过在等待回应中;
m :可能为分享的动态函式库;
-m选项可以查看文件所在的文件系统中有多少进程正在占用该文件系统
找到所有使用/proc这个文件系统的进程吧!
[root@initroot ~]# fuser -uv /proc
USER        PID ACCESS COMMAND
/proc:               root     kernel mount (root)/proc
rtkit      1436 .rc.. (rtkit)rtkit-daemon
            
数据量还不会很多,虽然这个目录很繁忙~没关系!我们可以继续这样作,看看其他的进程!
[root@initroot ~]# fuser -mvu /proc
USER        PID ACCESS COMMAND
/proc:               root     kernel mount (root)/proc
root          1 f.... (root)systemd
root        377 f.... (root)systemd-journal
systemd-resolve    580 f.... (systemd-resolve)systemd-resolve
syslog      708 f.... (syslog)rsyslogd
root        727 f.... (root)udisksd
root        964 F.... (root)Xorg
peter      1174 f.... (peter)systemd
peter      1428 f.... (peter)csd-housekeepin
rtkit      1436 .rc.. (rtkit)rtkit-daemon
peter      1474 f.... (peter)gvfs-udisks2-vo
peter      1553 f.... (peter)nemo-desktop
peter      1609 f.... (peter)gvfsd-trash
peter      2180 .rc.. (peter)Web Content
peter      2289 .rc.. (peter)WebExtensions
peter      2383 .rc.. (peter)Web Content
peter      3422 f.... (peter)nemo
peter      3941 .rc.. (peter)Web Content
peter      4371 f.... (peter)xreader
peter      4387 f.... (peter)WebKitNetworkPr
root       6620 f.... (root)systemd
有这几支进程在进行 /proc 文件系统的存取喔!这样清楚了吗?
范例三:找到所有使用到 /home 这个文件系统的进程吧!
先确认一下,自己的 bash PID 号码吧!
[root@initroot ~]# echo $$
31743
            
[root@initroot ~]# cd /home
[root@initroot home]# fuser -muv .
          USER PID ACCESS COMMAND
/home:    root kernel mount (root)/home
peter 31535 ..c.. (peter)bash
root 31571 ..c.. (root)passwd
root 31737 ..c.. (root)sudo
root 31743 ..c.. (root)bash
            
# 果然,自己的 PID 在啊!
[root@initroot home]# cd ~
[root@initroot ~]# umount /home
umount: /home: target is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
# 从 fuser 的结果可以知道,总共有五只 process 在该目录下运作,那即使 root 离开了 /home, # 当然还是无法 umount 的!那要怎办?哈哈!可以透过如下方法一个一个删除~
[root@initroot ~]# fuser -mki /home
/home:
31535c 31571c 31737c
# 你会发现, PID 跟上面查到的相同!
Kill process 31535 ? (y/N) 
# 这里会问你要不要删除!当然不要乱删除啦!通通取消! 既然可以针对整个文件系统,那么能不能仅针对单一文件啊?当然可以啰!
看一下底下的案例先:
范例四:找到 /run 底下属于 FIFO 类型的文件,并且找出存取该文件的进程
[root@initroot ~]# find /run -type p
.....(前面省略).....
/run/systemd/sessions/165.ref
/run/systemd/sessions/1.ref/run/systemd/sessions/c1.ref
# 随便抓个项目!就是这个好了!来测试一下!
[root@initroot ~]# fuser -uv /run/systemd/sessions/c1.ref
USER
PID ACCESS COMMAND
/run/systemd/sessions/c1.ref:
root 763 f.... (root)systemd-logind
root 5450 F.... (root)gdm-session-wor
通常系统的FIFO文件都会放置到/run目录下,透过这个方式来追踪该文件被存取的process!也能够晓得系统有多忙碌啊!
透过这个 fuser 我们可以找出使用该文件、目录的进程! 他的重点与 ps, pstree 不同。 fuser 可以让我们了解到某个文件 (或文件系统) 目前正在被哪些进程所利用!

2.lsof列出进程所打开的文件名

回到顶部
fuser是通过文件名找出占用该文件或者文件系统的进程,而lsof命令则可以查看进程打开的文件或者使用的文件系统。
[root@initroot ~]# lsof [-aUu] [+d]
选项与参数:
-a :多项数据需要同时成立才显示出结果时! -U :仅列出 Unix like 系统的 socket 文件类型; -u :后面接 username,列出该使用者相关进程所开启的文件; +d :后面接目录,亦即找出某个目录底下已经被开启的文件!
列出目前系统上面所有已经被开启的文件与装置:
[root@initroot ~]# lsof
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
      Output information may be incomplete.
COMMAND    PID  TID            USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
systemd      1                 root  cwd       DIR                8,1      4096          2 /
systemd      1                 root  rtd       DIR                8,1      4096          2 /
systemd      1                 root  txt       REG                8,1   1595792    1049085 /lib/systemd/systemd
systemd      1                 root  mem       REG                8,1   1700792    1053812 /lib/x86_64-linux-gnu/libm-2.27.so
systemd      1                 root  mem       REG                8,1    121016    1049149 /lib/x86_64-linux-gnu/libudev.so.1.6.9
systemd      1                 root  mem       REG                8,1     84032    1053790 /lib/x86_64-linux-gnu/libgpg-error.so.0.22.0
systemd      1                 root  mem       REG                8,1     43304    1053801 /lib/x86_64-linux-gnu/libjson-c.so.3.0.1
systemd      1                 root  mem       REG                8,1     34872     532281 /usr/lib/x86_64-linux-gnu/libargon2.so.0
...(省略)...
如果不加任何参数,lsof默认会将目前系统上面已经开启的文件全部列出来。可以看到目前系统中打开的文件非常多。可以注意到,第一个文件 systemd 执行的 地方就是根目录,而根目录所在的 inode 也有显示出来了!
仅列出关于 root 的所有进程开启的 socket 文件
[root@initroot ~]# lsof -u root -a -U
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
      Output information may be incomplete.
COMMAND    PID USER   FD   TYPE             DEVICE SIZE/OFF   NODE NAME
systemd      1 root   14u  unix 0xffff8c980d33e400      0t0  14487 /run/systemd/notify type=DGRAM
systemd      1 root   15u  unix 0xffff8c980d33e800      0t0  14488 type=DGRAM
systemd      1 root   16u  unix 0xffff8c980d33f400      0t0  14489 type=DGRAM
systemd      1 root   17u  unix 0xffff8c980d33e000      0t0  14490 /run/systemd/private type=STREAM
systemd      1 root   18u  unix 0xffff8c980dc44400      0t0  24013 /run/systemd/journal/stdout type=STREAM
systemd      1 root   19u  unix 0xffff8c980ddb3c00      0t0  24265 /run/systemd/journal/stdout type=STREAM
systemd      1 root   20u  unix 0xffff8c981625c800      0t0  24329 /run/systemd/journal/stdout type=STREAM
systemd      1 root   21u  unix 0xffff8c981625d800      0t0  24330 /run/systemd/journal/stdout type=STREAM
systemd      1 root   23u  unix 0xffff8c981833b400      0t0  23801 /run/systemd/journal/stdout type=STREAM
systemd      1 root   26u  unix 0xffff8c980d33f000      0t0  14502 /run/systemd/journal/stdout type=STREAM
systemd      1 root   27u  unix 0xffff8c980d33fc00      0t0  14504 /run/systemd/journal/socket type=DGRAM
systemd      1 root   32u  unix 0xffff8c980c8d3800      0t0  14543 /run/systemd/coredump type=SEQPACKET
systemd      1 root   33u  unix 0xffff8c980c8d3c00      0t0  14545 /run/systemd/fsck.progress type=STREAM
systemd      1 root   34u  unix 0xffff8c980c8d2000      0t0  14547 /run/udev/control type=SEQPACKET
systemd      1 root   35u  unix 0xffff8c980c8d3400      0t0  14550 /run/systemd/journal/dev-log type=DGRAM
systemd      1 root   37u  unix 0xffff8c980c8d2400      0t0  14559 /run/lvm/lvmpolld.socket type=STREAM
systemd      1 root   38u  unix 0xffff8c980c8d2c00      0t0  14563 /run/systemd/journal/syslog type=DGRAM
systemd      1 root   44u  unix 0xffff8c9816219000      0t0  14569 /run/lvm/lvmetad.socket type=STREAM
systemd      1 root   46u  unix 0xffff8c980ddb2800      0t0  15354 type=DGRAM
systemd      1 root   48u  unix 0xffff8c980dfbf800      0t0  16711 /run/systemd/journal/stdout type=STREAM
...(省略)...
注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥信息?
使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!-a 的用途就是在解决同时需要两个项目都成立时啊! ^_^
列出目前系统上面所有的被启动的设备:
[root@initroot ~]# lsof +d /dev
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
      Output information may be incomplete.
COMMAND    PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd      1            root    0u   CHR    1,3      0t0    6 /dev/null
systemd      1            root    1u   CHR    1,3      0t0    6 /dev/null
systemd      1            root    2u   CHR    1,3      0t0    6 /dev/null
systemd      1            root    3w   CHR   1,11      0t0   12 /dev/kmsg
systemd      1            root   24r   CHR 10,235      0t0  402 /dev/autofs
systemd      1            root   70u   CHR  10,62      0t0    4 /dev/rfkill
kdevtmpfs   15            root  cwd    DIR    0,6     4080    2 /dev
kdevtmpfs   15            root  rtd    DIR    0,6     4080    2 /dev
systemd-j  377            root    0r   CHR    1,3      0t0    6 /dev/null
systemd-j  377            root    1w   CHR    1,3      0t0    6 /dev/null
systemd-j  377            root    2w   CHR    1,3      0t0    6 /dev/null
systemd-j  377            root    7w   CHR   1,11      0t0   12 /dev/kmsg
systemd-j  377            root    9u   CHR   1,11      0t0   12 /dev/kmsg
lvmetad    405            root    0r   CHR    1,3      0t0    6 /dev/null
systemd-u  407            root    0r   CHR    1,3      0t0    6 /dev/null
systemd-r  580 systemd-resolve    0r   CHR    1,3      0t0    6 /dev/null
dbus-daem  586      messagebus    0u   CHR    1,3      0t0    6 /dev/null
            
# 看吧!因为装置都在 /dev 里面嘛!所以啰,使用搜寻目录即可啊!
秀出属于 root 的 bash 进程所开启的文件
[root@initroot ~]# lsof -u root | grep bash
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
      Output information may be incomplete.
bash      6632 root  cwd       DIR                8,1     4096    2621441 /root
bash      6632 root  rtd       DIR                8,1     4096          2 /
bash      6632 root  txt       REG                8,1  1113504    4456451 /bin/bash
bash      6632 root  mem       REG                8,1    47568    1053839 /lib/x86_64-linux-gnu/libnss_files-2.27.so
bash      6632 root  mem       REG                8,1    97176    1053833 /lib/x86_64-linux-gnu/libnsl-2.27.so
bash      6632 root  mem       REG                8,1    47576    1053850 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
bash      6632 root  mem       REG                8,1    39744    1053835 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
bash      6632 root  mem       REG                8,1  4795856     531033 /usr/lib/locale/locale-archive
bash      6632 root  mem       REG                8,1  2030544    1053749 /lib/x86_64-linux-gnu/libc-2.27.so
bash      6632 root  mem       REG                8,1    14560    1053772 /lib/x86_64-linux-gnu/libdl-2.27.so
bash      6632 root  mem       REG                8,1   170784    1053907 /lib/x86_64-linux-gnu/libtinfo.so.5.9
bash      6632 root  mem       REG                8,1   170960    1053721 /lib/x86_64-linux-gnu/ld-2.27.so
bash      6632 root  mem       REG                8,1    26376     790981 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
bash      6632 root    0u      CHR              136,0      0t0          3 /dev/pts/0
bash      6632 root    1u      CHR              136,0      0t0          3 /dev/pts/0
bash      6632 root    2u      CHR              136,0      0t0          3 /dev/pts/0
bash      6632 root  255u      CHR              136,0      0t0          3 /dev/pts/0
这个指令可以找出您想要知道的某个进程是否有启用哪些信息!

3.pidof通过进程名打印进程的PID

回到顶部
[root@initroot ~]# pidof [-sx] program_name
选项与参数:
-s :仅列出一个PID而不列出所有的PID
-x :同时列出该program name可能的PPID那个进程的PID
列出目前系统上面systemd以及rsyslogd这两个进程的PID
[root@initroot ~]# pidof systemd rsyslogd
6620 1174 708
# 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。 # 分别是 systemd 及 rsyslogd 这两支程序的 PID 啦。
很简单的用法吧,透过这个 pidof 指令,并且配合 ps aux 与正规表示法,就可以很轻易的找到您所想要的进程内容了呢。 如果要找的是bash ,那就 pidof bash ,立刻列出一堆PID号码了~

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读