Linux_Shell腳本學習第九章-明察秋毫(上)

一、監視磁盤使用情況

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章