一、监视磁盘使用情况
du(disk usage)和df (disk free)命令可以报告磁盘使用情况。这两个工具能够统计出文件和目录的磁盘占用情况以及可用的磁盘空间。
1.1 du
1.1.1 找出某个文件(或多个文件)占用的磁盘空间
$ du FILENAME1 FILENAME2 ..
要获得某个目录中所有文件的磁盘使用情况,并在每一行中显示各个文件的具体详情,可以使用:
$ du -a DIRECTORY
1.1.2 以KB、MB或块(block)为单位显示磁盘使用情况
du命令默认显示文件占用的总字节数,但是以KB、MB或GB为单位显示磁盘使用情况更方便人们阅读。要采用这种更友好的格式进行打印,可以使用选项-h:
du -h FILENAME
例如:
$ du -h test/pcpu.sh
4.0K test/pcpu.sh
# 可以接受多个文件参数
或者
# du -h DIRECTORY
$ du -h hack/
16K hack/
1.1.3 显示磁盘使用总计
选项-c可以计算出文件或目录所占用的总的磁盘空间,另外还会输出单个文件的大小:
$ du -c FILENAME1 FILENAME2..
du -c process_log.sh pcpu.sh
4 process_log.sh
4 pcpu.sh
8 total
或者
$ du -c DIRECTORY
$ du -c test/
16 test/
16 total
或者
$ du -c *.txt
# 通配符
1.1.4 使用特定的单位打印文件
选项-b、-k和-m可以强制du使用特定的单位打印磁盘使用情况。注意,这些选项不能与-h一同使用:
打印以字节(默认输出)为单位的文件大小:
$ du -b FILE(s)
打印以KB为单位的文件大小:
$ du -k FILE(s)
打印以MB为单位的文件大小:
$ du -m FILE(s)
打印以指定块为单位的文件大小:
$ du -B BLOCK_SIZE FILE(s)
其中,BLOCK_SIZE以字节为单位。
注意,上述选项返回的文件大小并不直观。如果使用选项-b,du会以字节为单位,返回文件的准确大小。如果使用的是其他选项,du返回的是文件所占的磁盘空间大小。因为磁盘空间是根据固定大小的块(通常是4K)来分配的,因此一个400字节的文件所占用的磁盘空间就是一个块(4K)。
$ du pcpu.sh
4 pcpu.sh
$ du -b pcpu.sh
439 pcpu.sh
$ du -k pcpu.sh
4 pcpu.sh
$ du -m pcpu.sh
1 pcpu.sh
$ du -B 4 pcpu.sh
1024 pcpu.sh
1.1.5 从磁盘使用统计中排除部分文件
选项–exclude和–exclude-from可以让du在磁盘使用统计中排除部分文件。
(1) 选项–exclude可以与通配符或单个文件名配合使用:
$ du --exclude "WILDCARD" DIRECTORY
例如:
# 排除所有的.txt文件
$ du --exclude "*.txt" *
# 排除文件temp.txt
$ du --exclude "temp.txt" *
(2) 选项–exclude会排除匹配模式的一个或多个文件。选项–exclude-from能够排除多个文件或模式。每个文件名或模式必须独占一行。
$ ls *.txt >EXCLUDE.txt
$ ls *.odt >>EXCLUDE.txt
# EXCLUDE.txt中包含了需要排除的文件列表
$ du --exclude-from EXCLUDE.txt DIRECTORY
选项–max-depth可以限制du应该遍历多少层子目录。将该选项指定为1,可以统计当前目录的磁盘使用情况。指定为2,可以统计当前目录以及下一级子目录的磁盘使用情况:
当使用du命令时,要确保其对所有的文件有读权限,对所有的目录有读权限和执行权限。如果权限不合适,du会返回出错信息。
1.1.6 找出指定目录中最大的10个文件
du和sort命令能够找出需要被删除或移走的大文件:
$ du -ak SOURCE_DIR | sort -nrk 1 | head
选项-a可以显示出SOURCE_DIR中所有文件和目录的大小。输出的第一列就是文件大小。选项-k表示以KB为单位。第二列包含文件或目录的名称。
sort的选项-n指明按数值排序,选项-l和-r指明对第一列按逆序排序。head用来从输出中提取前10行:
$ du -ak /home/slynux | sort -nrk 1 | head -n 4
50220 /home/slynux
43296 /home/slynux/.mozilla
43284 /home/slynux/.mozilla/firefox
43276 /home/slynux/.mozilla/firefox/8c22khxc.default
这个单行脚本的缺点之一在于它的结果中还包含了目录。我们可以使用find命令改进脚本,使其只输出最大的文件:
$ find . -type f -exec du -k {} \; | sort -nrk 1 | head
1.2 df
du提供磁盘使用情况信息,而df提供磁盘可用空间信息。df的-h选项会以易读的格式输出磁盘空间信息。例如:
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 9.2G 2.2G 6.6G 25% /
none 497M 240K 497M 1% /dev
none 502M 168K 501M 1% /dev/shm
none 502M 88K 501M 1% /var/run
none 502M 0 502M 0% /var/lock
none 502M 0 502M 0% /lib/init/rw
none 9.2G 2.2G 6.6G 25%
/var/lib/ureadahead/debugfs
df命令也可以使用目录作为参数。在这种情况下,会输出该目录所在分区的可用磁盘空间情况。如果你不知道目录所在分区的话,这种方法就很有用了:
$ df -h /home/user
Filesystem Size Used Avail Use% Mounted on
/dev/md1 917G 739G 133G 85% /raid1
二、计算命令执行时间
2.1 time命令可以测量出应用程序的执行时间
$ time APPLICATION
time命令会执行APPLICATION。当APPLICATION执行完毕后,time命令将其real时间、sys时间以及user时间输出到stderr中,将APPLICATION的正常输出发送到stdout。
$ time ls
test.txt
next.txt
real 0m0.008s
user 0m0.001s
sys 0m0.003s
2.2 选项-o可以将相关的时间统计信息写入文件
$ /usr/bin/time -o output.txt COMMAND
文件名应该出现在选项-o之后。
选项-a可以配合-o使用,将命令执行时间追加到原文件的末尾:
$ /usr/bin/time -a -o output.txt COMMAND
2.3 选项-f可以指定输出哪些统计信息及其格式
格式字符串包括一个或多个以%为前缀的参数。格式参数包括以下几种
real时间: %e
user时间: %U
sys时间: %S
系统分页大小:%Z
通过结合格式参数以及其他文本,我们就可以创建格式化输出:
$ /usr/bin/time -f "FORMAT STRING" COMMAND
例如:
$ /usr/bin/time -f "Time: %U" -a -o timing.log uname
Linux
其中,%U指定了user时间。
time命令将被计时的应用程序的输出发送到stdout,将自身的输出发送到stderr。我们可以用重定向操作符(>)重定向应用程序输出,用错误重定向操作符(2>)重定向time命令的输出。
例如:
$ /usr/bin/time -f "Time: %U" uname> command_output.txt 2>time.log
$ cat time.log
Time: 0.00
$ cat command_output.txt
Linux
2.4 格式参数也可以报告内存使用情况
参数%M会显示所使用的最大内存(以KB为单位),参数%Z会显示系统页面大小。
$ /usr/bin/time -f "Max: %M K\nPage size: %Z bytes" ls > /dev/null
Max: 996 K
Page size: 4096 bytes
2.5 time命令工作原理
time命令默认报告3类时间。
Real:指的是壁钟时间(wall clock time),也就是命令从开始执行到结束的时间。这段时间包括其他进程所占用的时间片(time slice)以及进程被阻塞时所消耗的时间(例如,为等待I/O操作完成所用的时间)。
User:是指进程花费在用户模式(内核模式之外)中的CPU时间。这是执行进程所花费的时间。执行其他进程以及花费在阻塞状态中的时间并没有计算在内。
Sys:是指进程花费在内核中的CPU时间。它代表在内核中执行系统调用所使用的时间,这和库代码(library code)不同,后者仍旧运行在用户空间。与“user时间”类似,这也是真正由进程使用的CPU时间。参考表9-1,其中简要描述了内核模式(也称为监督模式)和系统调用机制。
time命令给出了进程的很多细节信息。其中包括退出状态、接收到的信号数量以及进程上
下文的切换次数等。这些信息都可以通过给选项-f提供相应的格式化字符串来显示。
如下图
三、收集登录用户、启动日志及启动故障的相关信息
Linux包含了一些能够报告运行系统各方面信息的命令,其中包括当前登录用户、主机加电时间以及启动故障。这些数据可用于分配系统资源和故障诊断。
3.1 who
who命令可以获取当前登录用户的相关信息
$ who
slynux pts/0 2010-09-29 05:24 (slynuxs-macbook-pro.local)
slynux tty7 2010-09-29 07:08 (:0)
该命令会显示出登录名、用户所使用的TTY、登录时间以及登录用户的远程主机名(或者X显示信息)。
3.2 w
w命令可以获得有关登录用户更详细的信息
$ w
07:09:05 up 1:45, 2 users, load average: 0.12, 0.06, 0.02
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
slynux pts/0 slynuxs 05:24 0.00s 0.65s 0.11s sshd: slynux
slynux tty7 :0 07:08 1:45m 3.28s 0.26s bash
第一行列出了当前时间、系统运行时间、当前登录的用户数量以及过去的1/5/15分钟内的系统平均负载。接下来在每一行中显示了每个登录会话的详细信息,其中包括登录名、TTY、远程主机、登录时间、空闲时间、该用户登录后所使用的总CPU时间、当前运行进程所使用的CPU时间以及进程所对应的命令行。
3.3 users命令只列出当前的登录用户列表
$ users
slynux slynux slynux hacker
如果某个用户有多个登录会话,不管是远程登录还是打开了多个终端窗口,那么该用户会被多次显示。在上面的输出中,用户slynux打开了3个终端会话。排除重复用户的最简单的方法是使用sort和uniq进行过滤:
$ users | tr ' ' '\n' | sort | uniq
slynux
hacker
利用tr将’ ‘替换成’\n’,然后用sort和uniq为每个用户生成唯一的输出。
3.4 uptime命令可以查看系统的加电运行时长
$ uptime
21:44:33 up 6 days, 11:53, 8 users, load average: 0.09, 0.14,
0.09
单词up之后的时间表明了系统已经加电运行了多久。我们可以编写一个简单的单行脚本
来提取运行时间:
$ uptime | sed 's/.*up \(.*\),.*users.*/\1/'
sed使用单词up与第二个逗号(单词users之前)之间的内容替换掉整行文本。
3.5 last命令可以获取自文件/var/log/wtmp创建之后登录过系统的用户列表。这可能会追溯到一年之前(甚至更久):
$ last
aku1 pts/3 10.2.1.3 Tue May 16 08:23 - 16:14 (07:51)
cfly pts/0 cflynt.com Tue May 16 07:49 still logged in
dgpx pts/0 10.0.0.5 Tue May 16 06:19 - 06:27 (00:07)
stvl pts/0 10.2.1.4 Mon May 15 18:38 - 19:07 (00:29)
last命令会输出登录用户、用户所使用的tty、登录位置(IP地址或本地终端)、登录时间、登出时间、会话时长。伪用户名reboot表示系统重启。
3.6 ast命令也可以获取指定用户信息
$ last USER
上述命令中的USER可以是系统真实用户,也可以是伪用户reboot
$ last reboot
reboot system boot 2.6.32-21-generi Tue Sep 28 18:10 - 21:48
(03:37)
reboot system boot 2.6.32-21-generi Tue Sep 28 05:14 - 21:48
(16:33)
3.7 lastb命令可以获取失败的用户登录会话信息
# lastb
test tty8 :0 Wed Dec 15 03:56 - 03:56
(00:00)
slynux tty8 :0 Wed Dec 15 03:55 - 03:55
(00:00)
四、列出1 小时内占用CPU 最多的10 个进程
ps命令能够显示出系统中进程的详细信息。这些信息包括CPU使用情况、所执行的命令、内存占用、进程状态等。可以在脚本中使用ps命令识别出在一小时内占用CPU最多的进程。
用于监视并计算一小时内CPU使用情况的shell脚本:
#!/bin/bash
#文件名: pcpu_usage.sh
#用途:计算1个小时内进程的CPU占用情况
#将SECS更改成需要进行监视的总秒数
#UNIT_TIME是取样的时间间隔,单位是秒
SECS=3600
UNIT_TIME=60
STEPS=$(( $SECS / $UNIT_TIME ))
echo Watching CPU usage... ;
#采集数据,存入临时文件
for((i=0;i<STEPS;i++))
do
ps -eo comm,pcpu | egrep -v '(0.0)|(%CPU)' >> /tmp/cpu_usage.$$
sleep $UNIT_TIME
done
#处理采集到的数据
echo
echo CPU eaters :
cat /tmp/cpu_usage.$$ | \
awk '
{ process[$1]+=$2; }
END{
for(i in process)
{
printf("%-20s %s\n",i, process[i]) ;
}
}' | sort -nrk 2 | head
#删除临时日志文件
rm /tmp/cpu_usage.$$
输出如下:
$ ./pcpu_usage.sh
Watching CPU usage...
CPU eaters :
Xorg 20
firefox-bin 15
bash 3
evince 2
pulseaudio 1.0
pcpu.sh 0.3
wpa_supplicant 0
wnck-applet 0
watchdog/0 0
usb-storage 0
CPU的使用情况是由第一个循环负责生成的,该循环的执行时长为1小时(3600秒)。每隔1分钟命令ps -eocomm,pcpu就会产生一份系统活动报告。选项-e指定采集所有进程的数据,而不仅限于本次会话的进程。选项-o指定了输出格式。其中,comm指定输出命令名,pcpu指定输出CPU占用率。ps命令为每个进程输出一行,其中包含命令名及进程当时的CPU占用率。然后使用grep过滤这些行,删除未占用CPU的行(%CPU为0.0)以及头部信息COMMAND %CPU。处理后的结果被追加到临时文件中。
临时文件名为/tmp/cpu_usage.$$
。其中,$$是一个shell变量,值为当前脚本的进程ID(PID)。如果脚本的PID是1345,那么临时文件名就是/tmp/cpu_usage.1345。
统计文件在1小时后就准备妥当了,文件中包含了60项,分别对应每分钟的系统状态。awk计算出每个进程总的CPU使用情况并将其存入一个关联数组。该数组以进程名作为索引。最后根据总的CPU使用情况依数值执行逆序排序并利用head获得前10项。
五、使用watch 监视命令输出
watch命令会按照指定的间隔时间来执行命令并显示其输出。
$ watch COMMAND
例如
$ watch ls
或者
$ watch 'df /home'
考虑下面的例子:
# 只列出目录
$ watch 'ls -l | grep "^d"'
命令默认每2秒更新一次输出。
我们可以用-n SECONDS指定更新输出的时间间隔。例如:
#以5秒为间隔,监视ls -l的输出
$ watch -n 5 'ls -l'
选项-d能够着重标记出连续的命令输出之间的差异:
$ watch -d 'COMMANDS'
# 以30秒为间隔,着重标记出新的网络连接
$ watch -n 30 -d 'ss | grep ESTAB'
六、记录文件及目录访问情况
inotifywait命令可以用来监视目录:
#/bin/bash
#文件名: watchdir.sh
#用途:监视目录访问
path=$1
#将目录或文件路径作为脚本参数
inotifywait -m -r -e create,move,delete $path -q
输出样例如下:
$ ./watchdir.sh .
./ CREATE new
./ MOVED_FROM new
./ MOVED_TO news
./ DELETE news
上面的脚本能够记录指定路径中的创建、移动以及删除事件。选项-m表示持续监视变化,而不是在事件发生之后退出。选项-r允许采用递归形式监视目录(忽略符号链接)。选项-e指定需要监视的事件列表。选项-q用于减少冗余信息,只打印出所需要的信息。命令输出可以被重定向到日志文件。
inotifywait能够监视的事件如下图:
七、使用syslog 记录日志
与守护进程和系统进程相关的日志文件位于/var/log目录中。在Linux系统中,由守护进程sylogd使用syslog标准协议处理日志。每一个标准应用程序都可以利用syslogd记录日志。
日志文件有助于我们推断系统出现了什么故障。作为一种良好的实践,应当使用日志文件记录程序的执行过程。logger命令可以通过syslogd记录日志。
下图是一些标准的Linux日志文件。有些发行版采用了不同的文件名。
7.1 向日志文件/var/log/messages中写入信息
$ logger LOG_MESSAGE
例如:
$ logger This is a test log line
$ tail -n 1 /var/log/messages
Sep 29 07:47:44 slynux-laptop slynux: This is a test log line
/var/log/messages是一个通用日志文件。如果使用logger命令,它默认将日志写入/var/log/messages中。
7.2 选项-t可以定义消息标签
$ logger -t TAG This is a message
$ tail -n 1 /var/log/messages
Sep 29 07:48:42 slynux-laptop TAG: This is a message
选项-p和/etc/rsyslog.d/目录下的配置文件决定了日志消息保存到何处。
如果需要保存到指定的文件中,请按照以下步骤操作:
在/etc/rsyslog.d/下创建一个新的配置文件;
在配置文件中添加模式并指定日志文件;
重启日志守护进程(syslogd)。
考虑下面的例子:
# cat /etc/rsyslog.d/myConfig
local7.* /var/log/local7
# cd /etc/init.d
# ./syslogd restart
# logger -p local7.info #一行日志被写入/var/log/local7
7.3 选项-f可以将其他文件的内容记录到系统日志中
$ logger -f /var/log/source.log