18 进程
1. 查看进程⚓
1.1 ps⚓
静态查看。
ps aux 查看系统中所有的进程
ps -l 较长、较详细地输出信息
ps axjf 以进程树方式列出
-a 不与 terminal 有关的所有 process ;
-u 有效使用者 (effective user) 相关的 process ;
-e, -A 选择全部的进程
-f 完整格式地输出
Output formats:
x 通常与 a 这个参数一起使用,可列出较完整信息。注意,不是 -a 参数。aux 与 -aux 是不一样的!
f, --forest ascii art process tree
j BSD job control format
[root@dev ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 15352 3303 0 80 0 - 29238 do_wai pts/7 00:00:00 bash
0 R 0 17428 15352 0 80 0 - 38312 - pts/7 00:00:00 ps
各个字段的含义:
- F:进程的标志位。
- 1 forked but didn't exec
- 4 used super-user privileges
- S:进程的状态位。
- D uninterruptible sleep (usually IO)
- R running or runnable (on run queue)
- S interruptible sleep (waiting for an event to complete)
- T stopped by job control signal
- t stopped by debugger during the tracing
- W paging (not valid since the 2.6.xx kernel)
- X dead (should never be seen)
- Z defunct ("zombie") process, terminated but not reaped by its parent
- C:CPU使用率
- PRI:进程的优先级。数字越低优先级越高。
- NI:nice 值。范围: 19 (nicest) to -20 (not nice to others)。具体说明参考下文。
- ADDR:kernel function,指出该进程在内存的哪个部分,如果是个 running 的进程,一般就会显示
-
。 - SZ:在进程核心映像的物理页面中的大小。用掉多少内存。
- WCHAN:进程是处于休眠状态的kernel function名称。
-
代表running;*
代表多线程。 - TIME:此进程实际花费 CPU 运作的时间
[root@dev ~]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 194044 7216 ? Ss Nov04 0:09 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S Nov04 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< Nov04 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? S Nov04 0:01 [ksoftirqd/0]
……
root 18454 0.0 0.0 155372 1872 pts/7 R+ 15:15 0:00 ps aux
各个字段的含义:
- VSZ:该 process 使用掉的虚拟内存量 (Kbytes)
- RSS:该 process 占用的固定的内存量 (Kbytes)
- TTY:与终端无关时为
?
- STAT:同
S
- START:启动时间,若时间过长,则不会列出具体时间点
[root@dev ~]# ps axjf
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
3303 17492 17492 17492 pts/8 17534 Ss 0 0:00 \_ -bash
17492 17533 17533 17492 pts/8 17534 S 0 0:00 \_ su sink
17533 17534 17534 17492 pts/8 17534 S+ 1000 0:00 \_ bash
[root@dev ~]# ps axf
PID TTY STAT TIME COMMAND
1.2 top⚓
动态查看。
top -bcHiOSs -d secs -n max -u|U user -p pid -o fld -w [cols]
Options
-d 几秒更新一次
-b 批量模式。在将信息输出到其他程序或文件时很有用
-n 与 -b 搭配使用,表示迭代多少次
-o 按照哪个字段排序。在字段前添加特殊符号指定顺序还是降序:+表示降序排列;-表示升序排列。
# 3秒更新一次,以 PID 降序排序
[root@dev ~]# top -d 3 -o -PID
top - 09:52:18 up 2 days, 1:11, 10 users, load average: 0.37, 0.40, 0.34
Tasks: 292 total, 1 running, 291 sleeping, 0 stopped, 0 zombie
%Cpu(s): 4.1 us, 4.1 sy, 0.0 ni, 91.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16247672 total, 6168780 free, 5853688 used, 4225204 buff/cache
KiB Swap: 5242876 total, 5242876 free, 0 used. 9880640 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 194044 7216 4180 S 0.0 0.0 0:12.42 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.24 kthreadd
4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
上半部分的内容:
- 第一行:
- 当前时间是 09:52:18。
- 已经开机2天1小时11分钟了。
- 已登入系统的人数。同一个账户可在不同终端同时登入。
- 系统在 1, 5, 15 分钟的平均工作负载。工作负载是系统平均要负责运作几个进程(工作)的意思。
- 第二行,表示进程的总体状态
- 第三行,表示 CPU 的整体负载
- us, user : time running un-niced user processes
- sy, system : time running kernel processes
- ni, nice : time running niced user processes
- id, idle : time spent in the kernel idle handler,内核空闲
- wa, IO-wait : time waiting for I/O completion。如果是多核心的设备,可以按下数字键
1
来切换成不同CPU 的负载率。 - hi : time spent servicing hardware interrupts
- si : time spent servicing software interrupts
- st : time stolen from this vm by the hypervisor
- 第四行,表示物理内存的使用情况
- 第五行,表示虚拟内存的使用情况
下半部分的内容:
- PR:优先级
- NI:nice,与PR有关,也是越小越早被执行
# 将三次的结果输出到文件
[root@dev ~]# top -b -n 3 > top.log
# 只查看指定的进程
[root@dev ~]# top -p 1 -p 4
其实在执行top之后还有一些指令可以执行,按下h
来查看吧。
1.3 pstree⚓
显示进程树。
pstree [options] [pid, user]
options
-A Use ASCII characters to draw the tree.
-U Use UTF-8 (Unicode) line drawing characters.
-p Show PIDs.
-u Show uid transitions.
[root@dev ~]# pstree -pu | grep sink
| |-bash(17492)---su(17533)---bash(17534,sink)
[root@dev ~]# pstree -pu 2883
xdg-permission-(2883)─┬─{xdg-permission-}(2884)
└─{xdg-permission-}(2886)
[root@dev ~]# pstree -pu sink
bash(17534)
2. 结束进程⚓
killall
可以通过进程的名字来杀掉进程。
killall [options] [--] command_name ...
options
-e, --exact 精确匹配 command_name。不得超过15个字符
-i, --interactive 在 kill 进程之前交互式地询问
-I, --ignore-case 忽略大小写
-l, --list List all known signal names.
-s, --signal Send this signal instead of SIGTERM.
-u, --user Kill only processes the specified user owns.Command names are optional.
[root@dev ~]# killall -9 httpd
3. 进程执行顺序⚓
进程的优先执行序 (Priority) 与 CPU 排程。CPU 排程指的是每支进程被 CPU 运作的演算规则。
3.1 Priority 与 Nice 值⚓
PRI (Priority) 值是由内核动态调整的, 用户无法直接调整 PRI 值的。
如果你想要调整进程的优先执行序时,就得要透过 NI (Nice) 值了。
PRI 与 NI 的关系如下:
PRI(new) = PRI(old) + nice
虽然 nice 值是可以影响 PRI ,不过,最终的 PRI 仍是要经过系统分析后才会决定的。
NI 的使用事项:
-
nice 值可调整的范围为 -20 ~ 19 ;
-
root 可随意调整自己或他人进程的 Nice 值,且范围为 -20 ~ 19 ;
- 一般使用者仅可调整自己进程的 Nice 值,且范围仅为 0 ~ 19 (避免一般用户抢占系统资源);
- 一般使用者仅可将 nice 值越调越高,例如本来 nice 为 5 ,则未来仅能调整到大于 5;
在top运行的时候是可以通过键入r
来调整nice值的。下面介绍调整 NI 的另外两种方式。
3.1.1 nice:新执行的指令即给予新的 nice 值⚓
nice [OPTION] [COMMAND [ARG]...]
OPTION
-n, --adjustment=N add integer N to the niceness (default 10)
[root@dev ~]# nice -n -23 vi &
[root@dev ~]# vi &
[root@dev ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 15352 3303 0 80 0 - 29238 do_wai pts/7 00:00:00 bash
# 每次不一定会正好符合公式,内核会动态调整的
4 T 0 31430 15352 0 60 -20 - 31061 do_sig pts/7 00:00:00 vi
0 T 0 31444 15352 0 80 0 - 31061 do_sig pts/7 00:00:00 vi
0 R 0 31448 15352 0 80 0 - 38312 - pts/7 00:00:00 ps
[root@dev ~]# killall -9 vi
[1]- Killed nice -n -23 vi
[2]+ Killed vi
3.1.2 renice:对存在进程的 nice 重新调整⚓
renice [-n] priority [-gpu] identifier...
OPTIONS
-n, --priority priority 如果使用该选项,必须是第一个参数
-g, --pgrp pgid...
-u, --user name_or_uid...
-p, --pid pid...
# root用户调整
[root@dev ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 15352 3303 0 80 0 - 29238 do_wai pts/7 00:00:00 bash
0 R 0 31608 15352 0 80 0 - 38312 - pts/7 00:00:00 ps
[root@dev ~]# renice -n -5 15352
15352 (process ID) old priority 0, new priority -5
[root@dev ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 15352 3303 0 75 -5 - 29238 do_wai pts/7 00:00:00 bash
0 R 0 31615 15352 0 75 -5 - 38312 - pts/7 00:00:00 ps
[root@dev ~]# renice -n 5 15352
15352 (process ID) old priority -5, new priority 5
[root@dev ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 15352 3303 0 85 5 - 29238 do_wai pts/7 00:00:00 bash
0 R 0 31619 15352 0 85 5 - 38312 - pts/7 00:00:00 ps
# 普通用户调整
[sink@dev ~]$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 1000 17534 17533 0 80 0 - 29223 do_wai pts/8 00:00:00 bash
0 R 1000 31626 17534 0 80 0 - 38312 - pts/8 00:00:00 ps
[sink@dev ~]$ renice -n -10 17534
renice: failed to set priority for 17534 (process ID): Permission denied
[sink@dev ~]$ renice 3 17534
17534 (process ID) old priority 0, new priority 3
[sink@dev ~]$ ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 1000 17534 17533 0 83 3 - 29223 do_wai pts/8 00:00:00 bash
0 R 1000 31649 17534 0 83 3 - 38312 - pts/8 00:00:00 ps
在调整了 bash 的 nice 之后, ps 的nice 也跟着发生了变化,这是因为整个 nice 值是可以在父进程 --> 子进程之间传递的。
4. 特殊文件与进程⚓
4.1 具有 SUID/SGID 权限的指令执行状态⚓
在触发具有SUID
的程序后,会取得一个新的进程与 PID,该 PID 产生时透过 SUID 来给予该 PID 特殊的权限设定
[sink@dev ~]$ ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 27856 Aug 9 09:39 /usr/bin/passwd
[sink@dev ~]$ passwd
Changing password for user sink.
Changing password for sink.
# 此处按下 Ctl+Z 与 回车
(current) UNIX password:
[1]+ Stopped passwd
[sink@dev ~]$ pstree -pu | sed -n '/passwd/p'
| |-bash(17492)---su(34364)---bash(34365,sink)-+-passwd(35160,root)
可以看到父进程(bash(34365,sink))的用户是sink,但是其子进程(passwd(35160,root))的用户变为了root。
4.2 /proc/* 代表的意义⚓
进程都是在内存当中,而内存当中的数据又都是写入到 /proc/*
这个目录下的。基本上,目前主机上面的各个进程的 PID 都是以目录的型态存在于 /proc
当中。
[root@dev ~]# ll /proc/1/
total 0
dr-xr-xr-x. 2 root root 0 Nov 6 15:05 attr
-rw-r--r--. 1 root root 0 Nov 7 16:15 autogroup
-r--------. 1 root root 0 Nov 7 16:15 auxv
-r--r--r--. 1 root root 0 Nov 4 08:40 cgroup
……
重点在以下两个文件
- cmdline:这个进程被启动的指令串
- environ:这个进程的环境变量内容
[root@dev ~]# cat /proc/1/cmdline
/usr/lib/systemd/systemd--switched-root--system--deserialize22
包含了指令、选项与参数,针对的是进程;那么针对系统的文件就是直接在/proc/
目录下的文件啦。
4.3 查询已开启文件或已执行进程开启的文件⚓
4.3.1 fuser:由文件找进程⚓
fuser [-fuv] [-a|-s] [-4|-6] [-c|-m|-n space] [ -k [-i] [-M] [-w] [-SIGNAL] ] name ...
OPTIONS
-u,--user Append the user name of the process owner to each PID.
-v, --verbose 列出 USER, PID, ACCESS and COMMAND.
-a, --all Show all files specified on the command line.
-m,--mount show all processes using the named filesystems or block device
-i,--interactive ask before killing (ignored without -k)
-k,--kill kill processes accessing the named file
-SIGNAL send this signal instead of SIGKILL
[root@dev ~]# fuser -u /bin/bash
/usr/bin/bash: 3313e(root) 3366e(root) 3367e(root) 3819e(root) 3906e(root) 4051e(root) 4249e(root) 4569e(root) 15352e(root) 17492e(root) 34365e(sink) 92679e(root) 92736e(sink) 95880e(root) 108664e(root) 108729e(sink)
[root@dev ~]# fuser -uv /bin/bash
USER PID ACCESS COMMAND
/usr/bin/bash: root 3313 ...e. (root)bash
root 3366 ...e. (root)pycharm-start
root 3367 ...e. (root)pycharm.sh
root 3819 ...e. (root)bash
……
ACCESS所代表的意义:
- c current directory.
- e executable being run.
- f open file. f is omitted in default display mode.
- F open file for writing. F is omitted in default display mode.
- r root directory. 顶层目录
- m mmap'ed file or shared library.
[root@dev ~]# fuser -uv .top.log.swp
USER PID ACCESS COMMAND
/root/.top.log.swp: root 114662 F.... (root)vi
4.3.2 lsof:由进程找文件⚓
lsof [options] [ -- ] [names]
OPTIONS
-a 条件参数,意思是在两边的选项都成立时才列出,即逻辑与
-U 只列出 UNIX socket files.
-u s 列出该使用者相关进程所开启的文件。e.g., ``sink'', or ``548,root''.不能有空格
+D D 找出某个目录底下已经被开启的文件
-i [i]
-P 禁止将端口号转换为网络文件的端口名称。
[root@dev ~]# lsof | less
# NODE 即 inode
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 253,0 246 64 /
systemd 1 root rtd DIR 253,0 246 64 /
systemd 1 root txt REG 253,0 1624552 101335647 /usr/lib/systemd/systemd
systemd 1 root mem REG 253,0 20064 2142819 /usr/lib64/libuuid.so.1.3.0
# 既是 root 又是 socket 文件
[root@dev ~]# lsof -u root -a -U
……
# 网络文件
[root@dev ~]# lsof -u root -a -i 4 -P
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 42u IPv4 24643 0t0 TCP *:111 (LISTEN)
systemd 1 root 43u IPv4 24644 0t0 UDP *:111
sshd 1861 root 3u IPv4 33055 0t0 TCP *:22 (LISTEN)
cupsd 1863 root 12u IPv4 29388 0t0 TCP localhost:631 (LISTEN)
……
# 列出文件夹下被打开的文件
[root@dev ~]# lsof +d .
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
gnome-ses 2647 root cwd DIR 253,0 4096 67153985 .
……
4.3.3 pidof:查找正在运行的程序的进程 ID。⚓
pidof [options] program [program..]
OPTIONS
-s 只返回一个 pid
-x 同时列出该 program name 可能的 PPID 那个进程的 PID
# 普通用户也能查到 root 用户的进程
[sink@dev ~]$ pidof vi bash | xargs ps -fp
UID PID PPID C STIME TTY STAT TIME CMD
root 3313 3303 0 Nov04 pts/0 Ss 0:00 -bash
root 3366 3313 0 Nov04 pts/0 S+ 0:00 /bin/bash /usr/local/bin/pycharm-start
root 3819 3303 0 Nov04 pts/2 Ss 0:00 -bash
root 118382 17492 0 17:20 pts/8 T 0:00 vi top.log
……