v>
思考如下问题:
1.linux系统下运行着非常多的进程,如果系统资源非常紧张,如何找出做消耗系统资源的进程?
2.如果某个进程发生了错误,怎么找到这个错误进程并将其从linux系统中删除呢?
3.你可能希望某项工作能够快点运行完毕,如何让进程可以优先运行呢?
上面这些问题都涉及到进程的管理问题。
一个称职的linux系统管理员,必须要熟悉进程的管理流程才行,否则当系统发生问题时,还真的束手无策了! 下面我们就来详细了解系统的进程管理!
有很多命令可以查看系统中运行进程的状态信息,这些工具有ps、pstree和top等。其中ps和pstree可以静态的显示系统进程状态, 而top可以实时的动态显示系统进程的状态信息。
既然进程这么重要,那么我们如何查阅系统上面正在运作当中的进程呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅进程树之间的关系喔!
ps命令常用的命令格式如下所示:
只列出当前bash进程和相关进程信息:
上面的输出可以看出当前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观察进程信息:
使用ps -lA列出所有的进程信息
使用ps axjf以树状结构显示进程:
找出与cron与rsyslog这两个服务进程的PID:
如果你发现在某个进程的 CMD 后面还接上<defunct> 时,就代表该进程是僵尸进程啦,例如:
事实上,通常僵尸进程都已经无法控管,而直接是交给systemd进程来负责了,偏偏 systemd是系统第一支执行的程序, 他是所有程序的父程序! 我们无法杀掉该程序的 (杀掉他,系统就死掉了!),所以啰,如果产生僵尸进程, 而系统过一阵子还没有办法透过核心非经常性的特殊处理来将该进程删除时,那你只好透过reboot的方式来将该进程抹去了!
还有一些与进程有关的命令可以值得参考与应用
当你在删除某个文件时,这个文件却被某个进程占用着,这时候是不能删除的。那么怎么找到占用该文件的进程呢?
或者你用umount卸载某个文件系,却出现了device is busy的提示,这表明文件系统正在被某个进程使用。
这时候就可以使用fuser命令了。fuser语法有点像这样:
找到所有使用/proc这个文件系统的进程吧!
范例三:找到所有使用到 /home 这个文件系统的进程吧!
先确认一下,自己的 bash PID 号码吧!
看一下底下的案例先:
范例四:找到 /run 底下属于 FIFO 类型的文件,并且找出存取该文件的进程
透过这个 fuser 我们可以找出使用该文件、目录的进程! 他的重点与 ps, pstree 不同。 fuser 可以让我们了解到某个文件 (或文件系统) 目前正在被哪些进程所利用!
fuser是通过文件名找出占用该文件或者文件系统的进程,而lsof命令则可以查看进程打开的文件或者使用的文件系统。
仅列出关于 root 的所有进程开启的 socket 文件
使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!-a 的用途就是在解决同时需要两个项目都成立时啊! ^_^
列出目前系统上面所有的被启动的设备:
秀出属于 root 的 bash 进程所开启的文件
很简单的用法吧,透过这个 pidof 指令,并且配合 ps aux 与正规表示法,就可以很轻易的找到您所想要的进程内容了呢。 如果要找的是bash ,那就 pidof bash ,立刻列出一堆PID号码了~
linux ps命令
父目录:linux基础入门
- 一.linux进程管理
- 1.什么是进程(process)
- 2.进程与程序(process & program)
- 3.命令执行过程fork and exec
- 4.进程角度理解Linux的多用户多任务多终端环境
- 二.查看系统进程的状态信息
- 1.ps打印当前时刻进程的运行状态
- 2.top观察进程状态的动态变化
- 3.pstree以树状结构显示系统中进程的父子关系
- 三.kill或者killall给进程发送信号(signal)
- 四.进程优先级Priority和Nice值
- 1.nice :新执行的指令即给予新的 nice 值
- 2.renice :已存在进程的 nice 重新调整
- 五.进程特殊权限UUID、SUID、SGID
- 六./proc目录的意义
- 七.与进程相关的其他命令
- 1.fuser找出正在使用某个文件的进程
- 2.lsof列出进程所打开的文件名
- 3.pidof通过进程名打印进程的PID
二.查看系统进程的状态信息
回到顶部上面这些问题都涉及到进程的管理问题。
一个称职的linux系统管理员,必须要熟悉进程的管理流程才行,否则当系统发生问题时,还真的束手无策了! 下面我们就来详细了解系统的进程管理!
有很多命令可以查看系统中运行进程的状态信息,这些工具有ps、pstree和top等。其中ps和pstree可以静态的显示系统进程状态, 而top可以实时的动态显示系统进程的状态信息。
既然进程这么重要,那么我们如何查阅系统上面正在运作当中的进程呢?很简单啊! 利用静态的 ps 或者是动态的 top,还能以 pstree 来查阅进程树之间的关系喔!
1.ps打印当前时刻进程的运行状态
回到顶部[root@initroot ~]# ps aux #观察系统所有的进程数据 [root@initroot ~]# ps -lA #也是能够观察所有系统的数据 [root@initroot ~]# ps axjf #连同部分进程树状态选项与参数:
-A :显示系统中所有的进程,与-e具有同样的效用;ps默认只列出当前bash进程及其相关进程的信息,相关进程大多是bash的子进程。-l选项可以列出更加详细的进程信息。 更为常用的是显示系统中所有的进程状态信息ps aux.
-a :显示具有控制终端(terminal)的进程;
-u :有效用户(effective user)相关的process;
x :通常与a选项一起使用,可列出进程的较完整信息。
输出格式规划:
l :显示进程的详细信息;
j :工作的格式(jobs format);
-f :做一个更为完整的输出。
只列出当前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),常见号码有:bash进程的UID为0,这是普通用户peter的UID,也就是说这条进程是用户peter的进程。如果当前用户root,并且进程是由root触发的,那么进程的UID就是0了。 bash进程的状态为S睡眠(sleep), 之所以为睡眠因为他触发了ps(状态为run) 之故。PID为2062,,优先级为80, bash进程的终端接口为 pts/0 ,运行状态为等待(wait)
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环境只有两个进程,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 auxps aux输出的各字段和ps -l的输出有所不同,pa aux输出的各字段的意义为:
USER:该 process 的用户帐号名一般来说ps aux会按照PID的顺序来排序显示。我们以为上面的bash进程为例说明,该进程的执行用户为root,进程PID为31626,占用了0.2%的内存容百分比,状态为休眠(S), 该进程启动的时间为13:07,如果进程启动运行的时间很久,就不会列出实际的启动时间。这个bash是我刚刚通过ssh远程连接而启动的bash进程,控制终端为pts/0。
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 -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找出正在使用某个文件的进程
回到顶部[root@initroot ~]# fuser [-umv] [-k [i] [-signal]] file/dir选项与参数:
-u :除了进程的PID之外,同时列出该进程的拥有者;范例一:找出目前所在目录的使用 PID/所属账号/权限 为何? 看看有哪些进程正在使用当前工作目录:
-m :该文件所在的文件系统,后面接的那个文件名会主动的上提到该文件系统的最顶层,对umount不成功很有效!
-v :可以列出每个文件与进程还有指令的完整相关性!
-k :向找到的进程发送信号,信号由-signal指定,如果没有指定信号名或者信号编号,默认为SIGKILL信号;
-i :用户交互模式,必须与-k配合,在删除进程之前会先询问使用者!
-signal:例如 -1 -15 等等,若不加的话,默认是 SIGKILL (-9) 啰!
[root@initroot ~]# fuser -uv . USER PID ACCESS COMMAND /root: root 6632 ..c.. (root)bash正在使用当前工作目录的进程为bash进程,进程pid为6632,该进程属于root用户。比较有趣的是ACCESS字段,该字段代表的意义为:
c :此进程在当前的目录下(非次目录);-m选项可以查看文件所在的文件系统中有多少进程正在占用该文件系统
e :可被触发为执行状态;
f :是一个被开启的文件;
r :代表顶层目录(root directory);
F :该文件被开启了,不过在等待回应中;
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列出进程所打开的文件名
回到顶部[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列出目前系统上面systemd以及rsyslogd这两个进程的PID
-x :同时列出该program name可能的PPID那个进程的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次阅读