监测进程
探查进程
ps
当程序运行在系统上时,我们称之为进程(process)。想监测这些进程,需要熟悉ps命令的用法。ps命令好比工具中的瑞士军刀,它能输出运行在系统上的所有程序的许多信息。
遗憾的是,随着它的稳健而来的还有复杂性——有数不清的参数,这或许让ps命令成了最难掌握的命令。大多数系统管理员在掌握了能提供他们需要信息的一组参数之后,就一直坚持只使用这组参数。
默认情况下,ps命令并不会提供那么多的信息:
$ ps
PID TTY TIME CMD
3081 pts/0 00:00:00 bash
3209 pts/0 00:00:00 ps
$
默认情况下,ps命令只会显示运行在当前控制台下的属于当前用户的进程。在此例中,我们只运行了bash shell(注意,shell也只是运行在系统上的另一个程序而已)以及ps命令本身。
上例中的基本输出显示了程序的进程ID(Process ID,PID)、它们运行在哪个终端(TTY)以及进程已用的CPU时间。
一些常用参数:
-
-A :显示所有进程
-
-N :显示与指定参数不符的所有进程
-
-a :显示除控制进程(session leader①)和无终端进程外的所有进程
-
-d :显示除控制进程外的所有进程
-
-e :显示所有进程
-
-C cmdlist :显示包含在cmdlist列表中的进程
-
-G grplist :显示组ID在grplist列表中的进程
-
-U userlist :显示属主的用户ID在userlist列表中的进程
-
-g grplist :显示会话或组ID在grplist列表中的进程②
-
-p pidlist :显示PID在pidlist列表中的进程
使用ps命令的关键不在于记住所有可用的参数,而在于记住最有用的那些参数。
实时监测进程
top
ps命令虽然在收集运行在系统上的进程信息时非常有用,但也有不足之处:它只能显示某个特定时间点的信息。如果想观察那些频繁换进换出的内存的进程趋势,用ps命令就不方便了。
而top命令刚好适用这种情况。top命令跟ps命令相似,能够显示进程信息,但它是实时显示的。
-
PID:进程的ID。
-
USER:进程属主的名字。
-
PR:进程的优先级。
-
NI:进程的谦让度值。
-
VIRT:进程占用的虚拟内存总量。
-
RES:进程占用的物理内存总量。
-
SHR:进程和其他进程共享的内存总量。
-
S:进程的状态(D代表可中断的休眠状态,R代表在运行状态,S代表休眠状态,T代表跟踪状态或停止状态,Z代表僵化状态)。
-
%CPU:进程使用的CPU时间比例。
-
%MEM:进程使用的内存占可用内存的比例。
-
TIME+:自进程启动到目前为止的CPU时间总量。
-
COMMAND:进程所对应的命令行名称,也就是启动的程序名。
默认情况下,top命令在启动时会按照%CPU值对进程排序。可以在top运行时使用多种交互命令重新排序。每个交互式命令都是单字符,在top命令运行时键入可改变top的行为。键入f允许你选择对输出进行排序的字段,键入d允许你修改轮询间隔。键入q可以退出top。用户在top命令的输出上有很大的控制权。
结束进程
在Linux中,进程之间通过信号来通信。进程的信号就是预定义好的一个消息,进程能识别它并决定忽略还是作出反应。进程如何处理信号是由开发人员通过编程来决定的。大多数编写完善的程序都能接收和处理标准Unix进程信号。
| 信 号 | 名 称 | 描 述 |
|---|---|---|
| 1 | HUP | 挂起 |
| 2 | INT | 中断 |
| 3 | QUIT | 结束运行 |
| 9 | KILL | 无条件终止 |
| 11 | SEGV | 段错误 |
| 15 | TERM | 尽可能终止 |
| 17 | STOP | 无条件停止运行,但不终止 |
| 18 | TSTP | 停止或暂停,但继续在后台运行 |
| 19 | CONT | 在STOP或TSTP之后恢复执行 |
在Linux上有两个命令可以向运行中的进程发出进程信号。
kill
kill命令可通过进程ID(PID)给进程发信号。默认情况下,kill命令会向命令行中列出的全部PID发送一个TERM信号。遗憾的是,你只能用进程的PID而不能用命令名,所以kill命令有时并不好用。要发送进程信号,你必须是进程的属主或登录为root用户。
$ kill 3940
-bash: kill: (3940) - Operation not permitted
$
TERM信号告诉进程可能的话就停止运行。不过,如果有不服管教的进程,那它通常会忽略这个请求。如果要强制终止,-s参数支持指定其他信号(用信号名或信号值)
kill -s HUP 3940
killall
killall命令非常强大,它支持通过进程名而不是PID来结束进程。killall命令也支持通配符,这在系统因负载过大而变得很慢时很有用。
# killall http*
上例中的命令结束了所有以http开头的进程,比如Apache Web服务器的httpd服务。
以root用户身份登录系统时,使用killall命令要特别小心,因为很容易就会误用通配符而结束了重要的系统进程。这可能会破坏文件系统。
监测磁盘空间
挂载磁盘
Linux文件系统将所有的磁盘都并入一个虚拟目录下。在使用新的存储媒体之前,需要把它放到虚拟目录下。这项工作称为挂载(mounting)。
在今天的图形化桌面环境里,大多数Linux发行版都能自动挂载特定类型的可移动存储媒体。可移动存储媒体指的是可从PC上轻易移除的媒体,比如CD-ROM、软盘和U盘。
如果用的发行版不支持自动挂载和卸载可移动存储媒体,就必须手动完成。
mount
Linux上用来挂载媒体的命令叫作mount。默认情况下,mount命令会输出当前系统上挂载的设备列表。
$ mount
/dev/mapper/VolGroup00-LogVol00 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/sda1 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
/dev/sdb1 on /media/disk type vfat
(rw,nosuid,nodev,uhelper=hal,shortname=lower,uid=503)
$
mount命令提供如下四部分信息:
- 媒体的设备文件名
- 媒体挂载到虚拟目录的挂载点
- 文件系统类型
- 已挂载媒体的访问状态
上面例子的最后一行输出中,U盘被GNOME桌面自动挂载到了挂载点/media/disk。vfat文件系统类型说明它是在Windows机器上被格式化的。
要手动在虚拟目录中挂载设备,需要以root用户身份登录,或是以root用户身份运行sudo命令。下面是手动挂载媒体设备的基本命令:
mount -t type device directory
type参数指定了磁盘被格式化的文件系统类型。Linux可以识别非常多的文件系统类型。如果是和Windows PC共用这些存储设备,通常得使用下列文件系统类型。
- vfat:Windows长文件系统。
- ntfs:Windows NT、XP、Vista以及Windows 7中广泛使用的高级文件系统。
- iso9660:标准CD-ROM文件系统。
大多数U盘和软盘会被格式化成vfat文件系统。而数据CD则必须使用iso9660文件系统类型。
后面两个参数定义了该存储设备的设备文件的位置以及挂载点在虚拟目录中的位置。比如说,手动将U盘/dev/sdb1挂载到/media/disk,可用下面的命令:
mount -t vfat /dev/sdb1 /media/disk
媒体设备挂载到了虚拟目录后,root用户就有了对该设备的所有访问权限,而其他用户的访问则会被限制。你可以通过目录权限指定用户对设备的访问权限。
umount
从Linux系统上移除一个可移动设备时,不能直接从系统上移除,而应该先卸载。
卸载设备的命令是umount(是的,你没看错,命令名中并没有字母n,这一点有时候很让人困惑)。umount命令的格式非常简单:
umount [directory | device ]
umount命令支持通过设备文件或者是挂载点来指定要卸载的设备。如果有任何程序正在使用设备上的文件,系统就不会允许你卸载它
查看磁盘
df
有时你需要知道在某个设备上还有多少磁盘空间。df命令可以让你很方便地查看所有已挂载磁盘的使用情况。
命令输出如下:
-
设备的设备文件位置;
-
能容纳多少个1024字节大小的块;
-
已用了多少个1024字节大小的块;
-
还有多少个1024字节大小的块可用;
-
已用空间所占的比例;
-
设备挂载到了哪个挂载点上。
df命令有一些命令行参数可用,但基本上不会用到。一个常用的参数是-h。它会把输出中的磁盘空间按照用户易读的形式显示,通常用M来替代兆字节,用G替代吉字节。
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sdb2 18G 7.4G 9.2G 45% /
/dev/sda1 99M 19M 76M 20% /boot
tmpfs 117M 0 117M 0% /dev/shm
/dev/sdb1 125M 112M 14M 90% /media/disk
$
du
du命令可以显示某个特定目录(默认情况下是当前目录)的磁盘使用情况。这一方法可用来快速判断系统上某个目录下是不是有超大文件。默认情况下,du命令会显示当前目录下所有的文件、目录和子目录的磁盘使用情况
- -c:显示所有已列出文件总的大小。
- -h:按用户易读的格式输出大小,即用K替代千字节,用M替代兆字节,用G替代吉字节。
- -s:显示每个输出参数的总计。
处理数据文件
排序数据
sort
处理大量数据时的一个常用命令是sort命令。默认情况下,sort命令按照会话指定的默认语言的排序规则(统统按照字符串进行排序)对文本文件中的数据行排序。
- -n --numeric-sort 按字符串数值来排序(并不转换为浮点数)
- -r --reverse 反序排序(升序变成降序)
- -g --general-number-sort 按通用数值来排序(跟-n不同,把值当浮点数来排序,支持科学计数法表示的值)
- -k --key=POS1[,POS2] 排序从POS1位置开始;如果指定了POS2的话,到POS2位置结束(以POS1位置字段为准进行排序)
- -t --field-separator=SEP 指定一个用来区分键位置的字符(以SEP为区分符划分多个字段)
-k和-t参数在对按字段分隔的数据进行排序时非常有用,例如/etc/passwd文件。可以用-t参数来指定字段分隔符,然后用-k参数来指定排序的字段。
sort -t ':' -k 3 -n /etc/passwd
sort经常与管道符|结合起来使用
du -sh * | sort -nr
搜索数据
grep
grep [options] pattern [file]
grep命令会在输入或指定的文件中查找包含匹配指定模式的字符的行。grep的输出就是包含了匹配模式的行。
pattern通常是正则表达式
$ grep three file1
three
$ grep t file1
two
three
$
常用的功能参数有:
- -v:进行反向搜索(输出不匹配该模式的行)
- -n:显示匹配模式的行所在的行号
- -c:只显示有多少行含有匹配的模式
- -e:指定多个匹配模式
grep -e t -e f file1
压缩/归档数据文件
Linux包含了多种文件压缩工具。虽然听上去不错,但这实际上经常会在用户下载文件时造成混淆。
目前,Unix和Linux上最广泛使用的归档工具是tar命令。tar命令最开始是用来将文件写到磁带设备上归档的,然而它也能把输出写到文件里,这种用法在Linux上已经普遍用来归档数据了。
tar
tar function [options] object1 object2 ...
function参数定义了tar命令应该做什么
| 功 能 | 长 名称 | 描 述 |
|---|---|---|
| -A | --concatenate | 将一个已有tar归档文件追加到另一个已有tar归档文件 |
| -c | --create | 创建一个新的tar归档文件 |
| -d | --diff | 检查归档文件和文件系统的不同之处 |
| --delete | 从已有tar归档文件中删除 | |
| -r | --append | 追加文件到已有tar归档文件末尾 |
| -t | --list | 列出已有tar归档文件的内容 |
| -u | --update | 将比tar归档文件中已有的同名文件新的文件追加到该tar归档文件中 |
| -x | --extract | 从已有tar归档文件中提取文件 |
每个功能可用选项来针对tar归档文件定义一个特定行为。
| 选 项 | 描 述 |
|---|---|
| -C dir | 切换到指定目录 |
| -f file | 输出结果到文件或设备file |
| -j | 将输出重定向给bzip2命令来压缩内容 |
| -p | 保留所有文件权限 |
| -v | 在处理文件时显示文件 |
| -z | 将输出重定向给gzip命令来压缩内容 |
这些选项经常合并到一起使用。首先,你可以用下列命令来创建一个归档文件:
tar -cvf test.tar test/ test2/
上面的命令创建了名为test.tar的归档文件,含有test和test2目录内容
tar -tf test.tar 列出tar文件test.tar的内容(但并不提取文件)
tar -xvf test.tar 从tar文件test.tar中提取内容。如果tar文件是从一个目录结构创建的,那整个目
录结构都会在当前目录下重新创建。
内容来源
[1] [美] Richard Blum Christine Bresnahan.Linux命令行与shell脚本编程大全(第3版).北京人民邮电出版社,2016.