Linux 常用系統性能命令總結

Linux 常用系統性能命令

查看系統負載top,free

**w/uptime  **
最後面三個數字表示1分鐘,5分鐘,15分鐘平均有多少個進程佔用CPU佔用CPU的進程可以是Running,也可以是Waiting

某一時刻1顆CPU只能有一個進程在使用其資源

top命令:

top 回車就可以進入到top界面

每3秒刷新一次

默認按cpu百分比排序,可以按M鍵按照內存使用率大小排序

按數字1,可以顯示所有CPU使用率詳情

top -bn1 靜態顯示所有進程的情況,也是按cpu百分比排序

靜態顯示進程信息,方便在shell腳本中使用top命令

free命令:

free查看內存和swap使用情況,關注最後一列的available,這個數字是真正剩餘的物理內存大小

free -k -m -g -h

手動增加swap

dd if=/dev/zero of=/bigfile bs=1M count=1000

mkswap /bigfile

chmod 600 /bigfile

swapon /bigfile

監控磁盤 sysstat,iostat

iostat --> yum install -y sysstat

iostat -dx 1

iostat -dx 1 5

-c 顯示CPU使用情況

-d 顯示磁盤使用情況

-k 以K爲單位顯示

-m 以M爲單位顯示

-N 顯示磁盤陣列(LVM) 信息

-n 顯示NFS使用情況

-p 可以報告出每塊磁盤的每個分區的使用情況

-t 顯示終端和CPU的信息

-x 顯示詳細信息

示例1:

root\@localhost \~]\# iostat -x
Linux 3.10.0-693.el7.x86_64 (localhost.localdomain) 07/24/2019 \_x86_64\_ (1
CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
1.24 0.00 0.71 0.08 0.00 97.97
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await
w_await svctm %util
sda 27.94 8.17 17.76 9.01 589.90 138.94 54.44 0.08 2.88 2.64 3.33 0.20 0.54
scd0 0.00 0.00 0.00 0.00 0.02 0.00 90.26 0.00 0.48 0.48 0.00 0.43 0.00

輸出內容詳解:

%user:CPU處在用戶模式下的時間百分比

%nice:CPU處在帶NICE值的用戶模式下的時間百分比

%system:CPU處在系統模式下的時間百分比

%iowait:CPU等待輸入輸出完成時間的百分比

%steal:管理程序維護另一個虛擬處理器時,虛擬CPU的無意識等待時間百分比

%idle:CPU空閒時間百分比

當然了,iostat命令的重點不是用來看CPU的,重點是用來監測磁盤性能的。

Device:設備名稱

rrqm/s:每秒合併到設備的讀取請求數

wrqm/s:每秒合併到設備的寫請求數

r/s:每秒向磁盤發起的讀操作數

w/s:每秒向磁盤發起的寫操作數

rkB/s:每秒讀K字節數

wkB/s:每秒寫K字節數

avgrq-sz:平均每次設備I/O操作的數據大小

avgqu-sz:平均I/O隊列長度

await:平均每次設備I/O操作的等待時間
(毫秒),一般地,系統I/O響應時間應該低於5ms,如果大於 10ms就比較大了

r_await:每個讀操作平均所需的時間;不僅包括硬盤設備讀操作的時間,還包括了在kernel隊列中等待的時間

w_await:每個寫操作平均所需的時間;不僅包括硬盤設備寫操作的時間,還包括了在kernel隊列中等待的時間

svctm:平均每次設備I/O操作的服務時間 (毫秒)(這個數據不可信!)

%util:一秒中有百分之多少的時間用於I/O操作,即被IO消耗的CPU百分比,一般地,如果該參數是100%表示設備已經接近滿負荷運行了

----

[root\@localhost \~]\# iostat

Linux 3.10.0-693.el7.x86_64 (localhost.localdomain) 07/24/2019 \_x86_64\_ (1
CPU)

avg-cpu: %user %nice %system %iowait %steal %idle

1.23 0.00 0.71 0.08 0.00 97.97

Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn

sda 26.70 588.19 138.54 32169000 7576930

scd0 0.00 0.02 0.00 1038 0

輸出內容詳解:

cpu狀態

%user:CPU處在用戶模式下的時間百分比

%nice:CPU處在帶NICE值的用戶模式下的時間百分比

%system:CPU處在系統模式下的時間百分比

%iowait:CPU等待輸入輸出完成時間的百分比

%steal:管理程序維護另一個虛擬處理器時,虛擬CPU的無意識等待時間百分比

%idle:CPU空閒時間百分比

磁盤狀態

tps:每秒I/O數(即IOPS。磁盤連續讀和連續寫之和)

kB_read/s:每秒從磁盤讀取數據大小,單位KB/s

kB_wrtn/s:每秒寫入磁盤的數據的大小,單位KB/s

kB_read:從磁盤讀出的數據總數,單位KB

kB_wrtn:寫入磁盤的的數據總數,單位KB

iotop --> yum install -y iotop

iotop 回車 動態顯示,按IO使用率大小排序

綜合工具vmstat

vmstat 1

vmstat 1 10

常見選項:

-a:顯示活躍和非活躍內存

-f:顯示從系統啓動至今的fork數量 。

-m:顯示slabinfo

-n:只在開始時顯示一次各字段名稱。

-s:顯示內存相關統計信息及多種系統活動數量。

delay:刷新時間間隔。如果不指定,只顯示一條結果。

count:刷新次數。如果不指定刷新次數,但指定了刷新時間間隔,這時刷新次數爲無窮。

-d:顯示磁盤相關統計信息。

-p:顯示指定磁盤分區統計信息

-S:使用指定單位顯示。參數有 k 、K 、m 、M
,分別代表1000、1024、1000000、1048576字節(byte)。默認單位爲K(1024 bytes)

-V:顯示vmstat版本信息。

vmstat 命令詳解

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

r b swpd free inact active si so bi bo in cs us sy id wa st

3 0 122232 58944 208692 102840 137 60 580 136 117 111 1 1 98 0 0

Procs(進程)

r: 運行隊列中進程數量,這個值也可以判斷是否需要增加CPU。(長期大於1)

b 等待IO的進程數量。

Memory(內存)

swpd
使用虛擬內存大小,如果swpd的值不爲0,但是SI,SO的值長期爲0,這種情況不會影響系統性能。

free 空閒物理內存大小。

buff 用作緩衝的內存大小。

cache
用作緩存的內存大小,如果cache的值大的時候,說明cache處的文件數多,如果頻繁訪問到的文件都能被cache處,那麼磁盤的讀IO
bi會非常小。

Swap

si 每秒從交換區寫到內存的大小,由磁盤調入內存。

so 每秒寫入交換區的內存大小,由內存調入磁盤。

注意:內存夠用的時候,這2個值都是0,如果這2個值長期大於0時,系統性能會受到影響,磁盤IO和CPU資源都會被消耗。有些朋友看到空閒內存(free)很少的或接近於0時,就認爲內存不夠用了,不能光看這一點,還要結合si和so,如果free很少,但是si和so也很少(大多時候是0),那麼不用擔心,系統性能這時不會受到影響的。因爲linux總是先把內存用光

IO

bi 每秒讀取的塊數

bo 每秒寫入的塊數

注意:隨機磁盤讀寫的時候,這2個值越大(如超出1024k),能看到CPU在IO等待的值也會越大。

system(系統)

in 每秒中斷數,包括時鐘中斷。

cs 每秒上下文切換數。

注意:上面2個值越大,會看到由內核消耗的CPU時間會越大。

CPU(以百分比表示)

us 用戶進程執行時間百分比(user time)
us的值比較高時,說明用戶進程消耗的CPU時間多,但是如果長期超50%的使用,那麼我們就該考慮優化程序算法或者進行加速。

sy: 內核系統進程執行時間百分比(system time)
sy的值高時,說明系統內核消耗的CPU資源多,這並不是良性表現,我們應該檢查原因。

wa IO等待時間百分比
wa的值高時,說明IO等待比較嚴重,這可能由於磁盤大量作隨機訪問造成,也有可能磁盤出現瓶頸(塊操作)。

id 空閒時間百分比

關注:r、b、si、so、bi、bo、id、wa

vmstat –a 顯示活躍和非活躍內存,顯示增加了inact和active列

監控網卡流量sar,nload,iftop, ethtool

sar -n DEV 1 10

要判斷系統瓶頸問題,有時需幾個 sar 命令選項結合起來

懷疑CPU存在瓶頸,可用 sar -u 和 sar -q 等來查看

懷疑內存存在瓶頸,可用 sar -B、sar -r 和 sar -W 等來查看

懷疑I/O存在瓶頸,可用 sar -b、sar -u 和 sar -d 等來查看

懷疑網絡存在瓶頸,可以使用sar –n DEV 來進行查看。

yum install -y epel-release

yum install nload

nload 回車後查看網卡流量,動態顯示

擴展:

nload 默認分爲上下兩塊(如上圖):

上半部分是:Incoming也就是進入網卡的流量,

下半部分是:Outgoing,也就是從這塊網卡出去的流量,

每部分都有當前流量(Curr),

平均流量(Avg),

最小流量(Min),

最大流量(Max),

總和流量(Ttl)

nload默認的是eth0網卡,如果你想監測eth1網卡的流量#nload eth1

---------------------

ethtool ens33 #查看網卡信息

ethtool --identify eth2 20

這個意思是說,讓eth2標識的網卡的燈點亮20秒!如果網卡標號與網卡實際的物理位置關係亂了,你又不知道eth2是哪個網卡,上述網卡點燈程序就會讓你知道了。

mii-tool ens33 #查看網卡硬件信息

查看進程 ps,top

ps aux 、 ps -elf 、

ps -eLf (查看線程)

top –Hp pid號 (查看線程)

STAT

S Sleep

R Running

s 父進程

N 低優先級

< 高優先級

  • 前臺進程

l 多線程進程

Z 殭屍進程

ls -l /proc/pid號/ #查看一個進程的一些詳細信息

查看網絡連接狀況:

netstat -lnp 、netstat -lntp 、 netstat -lntup

netstat -an

ss -an

抓包工具 tcpdump,wireshark

wireshark (安裝:yum install -y wireshark)

tshark -i ens33 -n -t a -R http.request -T fields -e "frame.time" -e "ip.src" -e
"http.host" -e "http.request.method" -e "http.request.uri"

補充:

查看cpu核數

cat /proc/cpuinfo

lscpu

buffer和cached 詳解

buffer : 這部分內存是從CPU產生即將寫入到磁盤裏去的那部分數據;

cached 這部分數據是先從磁盤裏讀出來,然 後臨時存到內存裏的那部分數據,

小常識:

bit 比特(帶寬單位)

Byte 字節 (速度傳輸單位)

8bit = 1Byte 2MB/s 2*8=16Mbit 100Mbit 12.8MB/s

抓包工具tcpdump用法說明

tcpdump (安裝:yum install -y tcpdump)

tcpdump -nn -i ens33 port 80

tcpdump -nn -i ens33 -c 100 -w 1.cap

tcpdump -i ens33 -nn not port 22 and not port 80 and not host 192.168.222.1

tcpdump -nn -r 1.cap

tcpdump採用命令行方式對接口的數據包進行篩選抓取,其豐富特性表現在靈活的表達式上。

不帶任何選項的tcpdump,默認會抓取第一個網絡接口,且只有將tcpdump進程終止纔會停止抓包。

例如:

shell> tcpdump -nn -i eth0 icmp

下面是詳細的tcpdump用法。

1.1 tcpdump選項

它的命令格式爲:

tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ] [ -s
snaplen ] [ -w file ] [ expression ]

抓包選項:

-c:指定要抓取的包數量。注意,是最終要獲取這麼多個包。例如,指定"-c
10"將獲取10個包,但可能已經處理了100個包,只不過只有10個包是滿足條件的包。

-i
interface:指定tcpdump需要監聽的接口。若未指定該選項,將從系統接口列表中搜尋編號最小的已配置好的接口(不包括loopback接口,要抓取loopback接口使用tcpdump
-i
lo),一旦找到第一個符合條件的接口,搜尋馬上結束。可以使用'any'關鍵字表示所有網絡接口。

-n:對地址以數字方式顯式,否則顯式爲主機名,也就是說-n選項不做主機名解析。

-nn:除了-n的作用外,還把端口顯示爲數值,否則顯示端口服務名。

-N:不打印出host的域名部分。例如tcpdump將會打印'nic'而不是'nic.ddn.mil'。

-P:指定要抓取的包是流入還是流出的包。可以給定的值爲"in"、"out"和"inout",默認爲"inout"。

-s
len:設置tcpdump的數據包抓取長度爲len,如果不設置默認將會是65535字節。對於要抓取的數據包較大時,長度設置不夠可能會產生包截斷,若出現包截斷,輸出行中會出現"[|proto]"的標誌(proto實際會顯示爲協議名)。但是抓取len越長,包的處理時間越長,並且會減少tcpdump可緩存的數據包的數量,從而會導致數據包的丟失,所以在能抓取我們想要的包的前提下,抓取長度越小越好。

輸出選項:

-e:輸出的每行中都將包括數據鏈路層頭部信息,例如源MAC和目標MAC

-q:快速打印輸出。即打印很少的協議相關信息,從而輸出行都比較簡短。

-X:輸出包的頭部數據,會以16進制和ASCII兩種方式同時輸出。

-XX:輸出包的頭部數據,會以16進制和ASCII兩種方式同時輸出,更詳細。

-v:當分析和打印的時候,產生詳細的輸出。

-vv:產生比-v更詳細的輸出。

-vvv:產生比-vv更詳細的輸出。

其他功能性選項:

-D:列出可用於抓包的接口。將會列出接口的數值編號和接口名,它們都可以用於"-i"後。

-F:從文件中讀取抓包的表達式。若使用該選項,則命令行中給定的其他表達式都將失效。

-w:將抓包數據輸出到文件中而不是標準輸出。可以同時配合"-G
time"選項使得輸出文件每time秒就自動切換到另一個文件。可通過"-r"選項載入這些文件以進行分析和打印。

-r:從給定的數據包文件中讀取數據。使用"-"表示從標準輸入中讀取。

所以常用的選項也就這幾個:

tcpdump -D

tcpdump -c num -i int -nn -XX –vvv

1.2 tcpdump表達式

表達式用於篩選輸出哪些類型的數據包,如果沒有給定表達式,所有的數據包都將輸出,否則只輸出表達式爲true的包。在表達式中出現的shell元字符建議使用單引號包圍。

tcpdump的表達式由一個或多個"單元"組成,每個單元一般包含ID的修飾符和一個ID(數字或名稱)。

有三種修飾符:

(1).type:指定ID的類型。

可以給定的值有host/net/port/portrange。例如"host foo","net 128.3","port
20","portrange 6000-6008"。默認的type爲host。

(2).dir:指定ID的方向。

可以給定的值包括src/dst/src or dst/src and dst,默認爲src or dst。例如,"src
foo"表示源主機爲foo的數據包,"dst net 128.3"表示目標網絡爲128.3的數據包,"src or
dst port 22"表示源或目的端口爲22的數據包。

(3).proto:通過給定協議限定匹配的數據包類型。

常用的協議有tcp/udp/arp/ip/ether/icmp等,若未給定協議類型,則匹配所有可能的類型。例如"tcp
port 21","udp portrange 7000-7009"。

所以,一個基本的表達式單元格式爲"proto dir type ID"

除了使用修飾符和ID組成的表達式單元,還有關鍵字表達式單元:gateway,broadcast,less,greater以及算術表達式。

表達式單元之間可以使用操作符" and / && / or / || / not / !
"進行連接,從而組成複雜的條件表達式。
如"host foo and not port ftp and not port
ftp-data",這表示篩選的數據包要滿足"主機爲foo且端口不是ftp(端口21)和ftp-data(端口20)的包",常用端口和名字的對應關係可在linux系統中的/etc/service文件中找到。

另外,同樣的修飾符可省略,如"tcp dst port ftp or ftp-data or domain"與"tcp dst
port ftp or tcp dst port ftp-data or tcp dst port
domain"
意義相同,都表示包的協議爲tcp且目的端口爲ftp或ftp-data或domain(端口53)。

使用括號"()"可以改變表達式的優先級,但需要注意的是括號會被shell解釋,所以應該使用反斜線"\"轉義爲"\(\)",在需要的時候,還需要包圍在引號中。

1.3 tcpdump示例

注意,tcpdump只能抓取流經本機的數據包。

(1).默認啓動

tcpdump

默認情況下,直接啓動tcpdump將監視第一個網絡接口(非lo口)上所有流通的數據包。這樣抓取的結果會非常多,滾動非常快。

(2).監視指定網絡接口的數據包

tcpdump -i eth1

如果不指定網卡,默認tcpdump只會監視第一個網絡接口,如eth0。

(3).監視指定主機的數據包,例如所有進入或離開longshuai的數據包

tcpdump host longshuai

(4).打印helios<-->hot或helios<-->ace之間通信的數據包

tcpdump host helios and \( hot or ace \)

(5).打印ace與任何其他主機之間通信的IP數據包,但不包括與helios之間的數據包

tcpdump ip host ace and not helios

(6).截獲主機hostname發送的所有數據

tcpdump src host hostname

(7).監視所有發送到主機hostname的數據包

tcpdump dst host hostname

(8).監視指定主機和端口的數據包

tcpdump tcp port 22 and host hostname

(9).對本機的udp 123端口進行監視(123爲ntp的服務端口)

tcpdump udp port 123

(10).監視指定網絡的數據包,如本機與192.168網段通信的數據包,"-c
10"表示只抓取10個包

tcpdump -c 10 net 192.168

(11).打印所有通過網關snup的ftp數據包(注意,表達式被單引號括起來了,這可以防止shell對其中的括號進行錯誤解析)

shell> tcpdump 'gateway snup and (port ftp or ftp-data)'

(12).抓取ping包

[root@server2 ~]# tcpdump -c 5 -nn -i eth0 icmp

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

12:11:23.273638 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id
16422, seq 10, length 64

12:11:23.273666 IP 192.168.100.62 > 192.168.100.70: ICMP echo reply, id 16422,
seq 10, length 64

12:11:24.356915 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id
16422, seq 11, length 64

12:11:24.356936 IP 192.168.100.62 > 192.168.100.70: ICMP echo reply, id 16422,
seq 11, length 64

12:11:25.440887 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id
16422, seq 12, length 64

5 packets captured

6 packets received by filter

0 packets dropped by kernel

如果明確要抓取主機爲192.168.100.70對本機的ping,則使用and操作符。

[root@server2 ~]# tcpdump -c 5 -nn -i eth0 icmp and src 192.168.100.62

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

12:09:29.957132 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id
16166, seq 1, length 64

12:09:31.041035 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id
16166, seq 2, length 64

12:09:32.124562 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id
16166, seq 3, length 64

12:09:33.208514 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id
16166, seq 4, length 64

12:09:34.292222 IP 192.168.100.70 > 192.168.100.62: ICMP echo request, id
16166, seq 5, length 64

5 packets captured

5 packets received by filter

0 packets dropped by kernel

注意不能直接寫icmp src 192.168.100.70,因爲icmp協議不支持直接應用host這個type。

(13).抓取到本機22端口包

[root@server2 ~]# tcpdump -c 10 -nn -i eth0 tcp dst port 22

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

12:06:57.574293 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack
535528834, win 2053, length 0

12:06:57.629125 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 193,
win 2052, length 0

12:06:57.684688 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 385,
win 2051, length 0

12:06:57.738977 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 577,
win 2050, length 0

12:06:57.794305 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 769,
win 2050, length 0

12:06:57.848720 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 961,
win 2049, length 0

12:06:57.904057 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 1153,
win 2048, length 0

12:06:57.958477 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 1345,
win 2047, length 0

12:06:58.014338 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 1537,
win 2053, length 0

12:06:58.069361 IP 192.168.100.1.5788 > 192.168.100.62.22: Flags [.], ack 1729,
win 2052, length 0

10 packets captured

10 packets received by filter

0 packets dropped by kernel

(14).解析包數據

[root\@server2 \~]\# tcpdump -c 2 -q -XX -vvv -nn -i eth0 tcp dst port 22

tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535
bytes

12:15:54.788812 IP (tos 0x0, ttl 64, id 19303, offset 0, flags [DF], proto TCP
(6), length 40)

192.168.100.1.5788 \> 192.168.100.62.22: tcp 0

0x0000: 000c 2908 9234 0050 56c0 0008 0800 4500 ..)..4.PV.....E.

0x0010: 0028 4b67 4000 4006 a5d8 c0a8 6401 c0a8 .(Kg\@.\@.....d...

0x0020: 643e 169c 0016 2426 5fd6 1fec 2b62 5010 d\>....\$&_...+bP.

0x0030: 0803 7844 0000 0000 0000 0000 ..xD........

12:15:54.842641 IP (tos 0x0, ttl 64, id 19304, offset 0, flags [DF], proto TCP
(6), length 40)

192.168.100.1.5788 \> 192.168.100.62.22: tcp 0

0x0000: 000c 2908 9234 0050 56c0 0008 0800 4500 ..)..4.PV.....E.

0x0010: 0028 4b68 4000 4006 a5d7 c0a8 6401 c0a8 .(Kh\@.\@.....d...

0x0020: 643e 169c 0016 2426 5fd6 1fec 2d62 5010 d\>....\$&_...-bP.

0x0030: 0801 7646 0000 0000 0000 0000 ..vF........

2 packets captured

2 packets received by filter

0 packets dropped by kernel

總的來說,tcpdump對基本的數據包抓取方法還是較簡單的。只要掌握有限的幾個選項(-nn
-XX -vvv -i -c -q),再組合表達式即可。

  1. Http 訪問分析命令curl
    1. Curl 的實戰案例測試詳解

curl語法結構如下:

curl [options...] <url>

常用選項:

-v 詳細輸出,包含請求和響應的首部

-o test 將指定curl返回保存爲test文件,內容從html/jpg到各種MIME類型文件

-O 把輸出寫到該文件中,保留遠程文件的文件名

-C 在保存文件時進行續傳

-x ip:port 指定使用的http代理

-c <file> 保存服務器的cookie文件

-H <header:value> 爲HTTP請求設置任意header及值

-L 跟隨重定向

-S 顯示錯誤信息

-s 靜默模式,不輸出任何信息

-G 以get的方式發送數據

-f 連接失敗是不顯示http錯誤

-d 以post方式傳送數據

-A 自定義 User-Agent

實例:

  1. 獲取頁面內容

當我們不加任何選項使用 curl 時,默認會發送 GET 請求來獲取鏈接內容到標準輸出。

curl http://www.codebelief.com

  1. 顯示 HTTP 頭

如果我們只想要顯示 HTTP 頭,而不顯示文件內容,可以使用 -I 選項:

curl -I http://www.codebelief.com

輸出爲:

HTTP/1.1 200 OK

Server: nginx/1.10.3

Date: Thu, 11 May 2017 08:24:45 GMT

Content-Type: text/html; charset=utf-8

Content-Length: 24206

Connection: keep-alive

X-Powered-By: Express

Cache-Control: public, max-age=0

ETag: W/"5e8e-Yw5ZdnVVly9/aEnMX7fVXQ"

Vary: Accept-Encoding

也可以同時顯示 HTTP 頭和文件內容,使用 -i 選項:

curl -i http://www.codebelief.com

輸出爲:

HTTP/1.1 200 OK

Server: nginx/1.10.3

Date: Thu, 11 May 2017 08:25:46 GMT

Content-Type: text/html; charset=utf-8

Content-Length: 24206

Connection: keep-alive

X-Powered-By: Express

Cache-Control: public, max-age=0

ETag: W/"5e8e-Yw5ZdnVVly9/aEnMX7fVXQ"

Vary: Accept-Encoding

\<!DOCTYPE html\>

\<html lang="en"\>

......

\</html\>
  1. 將鏈接保存到文件

我們可以使用 > 符號將輸出重定向到本地文件中。

curl http://www.codebelief.com > index.html

也可以通過 curl 自帶的 -o/-O 選項將內容保存到文件中。

-o(小寫的 o):結果會被保存到命令行中提供的文件名

-O(大寫的 O):URL 中的文件名會被用作保存輸出的文件名

curl -o index.html http://www.codebelief.com

curl -O http://www.codebelief.com/page/2/

注意:使用 -O 選項時,必須確保鏈接末尾包含文件名,否則 curl
無法正確保存文件。如果遇到鏈接中無文件名的情況,應該使用 -o
選項手動指定文件名,或使用重定向符號。

  1. 同時下載多個文件

我們可以使用 -o 或 -O 選項來同時指定多個鏈接,按照以下格式編寫命令:

curl -O http://www.codebelief.com/page/2/ -O http://www.codebelief.com/page/3/

或者:

curl -o page1.html http://www.codebelief.com/page/1/ -o page2.html
http://www.codebelief.com/page/2/

  1. 使用 -L 跟隨鏈接重定向

如果直接使用 curl
打開某些被重定向後的鏈接,這種情況下就無法獲取我們想要的網頁內容。例如:

curl http://codebelief.com

會得到如下提示:

<html>

<head><title>301 Moved Permanently</title></head>

<body bgcolor="white">

<center><h1>301 Moved Permanently</h1></center>

<hr><center>nginx/1.10.3</center>

</body>

</html>

而當我們通過瀏覽器打開該鏈接時,會自動跳轉到
http://www.codebelief.com。此時我們想要 curl
做的,就是像瀏覽器一樣跟隨鏈接的跳轉,獲取最終的網頁內容。我們可以在命令中添加
-L 選項來跟隨鏈接重定向:

curl -L http://codebelief.com

這樣我們就能獲取到經過重定向後的網頁內容了。

  1. 使用 -A 自定義 User-Agent

我們可以使用 -A
來自定義用戶代理,例如下面的命令將僞裝成安卓火狐瀏覽器對網頁進行請求:

curl -A "Mozilla/5.0 (Android; Mobile; rv:35.0) Gecko/35.0 Firefox/35.0"
http://www.baidu.com

下面我們會使用 -H 來實現同樣的目的。

  1. 使用 -H 自定義 header

當我們需要傳遞特定的 header 的時候,可以仿照以下命令來寫

curl -H "Referer: www.example.com" -H "User-Agent: Custom-User-Agent"
http://192.168.0.215

可以看到,當我們使用 -H 來自定義 User-Agent 時,需要使用 "User-Agent: xxx"
的格式。

我們能夠直接在 header 中傳遞 Cookie,格式與上面的例子一樣:

curl -H "Cookie: JSESSIONID=D0112A5063D938586B659EF8F939BE24"
http://www.example.com

另一種方式會在下面介紹。

  1. 使用 -c 保存 Cookie

當我們使用 cURL 訪問頁面的時候,默認是不會保存 Cookie 的。有些情況下我們希望保存
Cookie
以便下次訪問時使用。例如登陸了某個網站,我們希望再次訪問該網站時保持登陸的狀態,這時就可以現將登陸時的
Cookie 保存起來,下次訪問時再讀取。

-c 後面跟上要保存的文件名。

curl -c "cookie-example" http://www.example.com

  1. 使用 -b 讀取 Cookie

前面講到了使用 -H 來發送 Cookie 的方法,這種方式是直接將 Cookie
字符串寫在命令中。如果使用 -b 來自定義 Cookie,命令如下:

curl -b "JSESSIONID=D0112A5063D938586B659EF8F939BE24" http://www.example.com

如果要從文件中讀取 Cookie,-H 就無能爲力了,此時可以使用 -b 來達到這一目的:

curl -b "cookie-example" http://www.example.com

即 -b 後面既可以是 Cookie 字符串,也可以是保存了 Cookie 的文件名。

  1. 使用 -d 發送 POST 請求

我們以登陸網頁爲例來進行說明使用 curl 發送 POST 請求的方法。假設有一個登錄頁面
www.example.com/login,只需要提交用戶名和密碼便可登錄。我們可以使用 cURL
來完成這一 POST 請求,-d 用於指定發送的數據,-X 用於指定發送數據的方式:

curl -d "userName=tom&passwd=123456" -X POST http://www.example.com/login

在使用 -d 的情況下,如果省略 -X,則默認爲 POST 方式:

curl -d "userName=tom&passwd=123456" http://www.example.com/login

強制使用 GET 方式

發送數據時,不僅可以使用 POST 方式,也可以使用 GET 方式,例如:

curl -d "somedata" -X GET http://www.example.com/api

或者使用 -G 選項:

curl -d "somedata" -G http://www.example.com/api

從文件中讀取 data

curl -d "@data.txt" http://www.example.com/login

帶 Cookie 登錄

當然,如果我們再次訪問該網站,仍然會變成未登錄的狀態。我們可以用之前提到的方法保存
Cookie,在每次訪問網站時都帶上該 Cookie 以保持登錄狀態。

curl -c "cookie-login" -d "userName=tom&passwd=123456"
http://www.example.com/login

再次訪問該網站時,使用以下命令:

curl -b "cookie-login" http://www.example.com/login

這樣,就能保持訪問的是登錄後的頁面了。

curl命令來路僞裝(referer)和瀏覽器僞裝(user-agent)

一般的知名站點,都有一套比較完善的機器流量檢測系統;它通過流量的IP、流量的來源、使用的瀏覽設備、訪問頻次、用戶行爲等綜合分析,來判斷當前流量是真實的用戶流量,還是機器在爬網站的數據,從而做出是否封禁當前流量的決定。第三方統計站點,也是使用此原理來幫助站長統計用戶行文的。

而其中的流量來源、使用的瀏覽設備、甚至流量的IP都是可以僞造的。本文爲介紹curl僞裝訪問來源、和僞裝使用的瀏覽器的方法。僞裝來路IP地址,請參考“linux
curl命令使用代理服務器”。

一、原理說明:

瀏覽器與http服務器是通過http協議通訊的,而http請求頭中包含了客戶端的一些信息,其中包括:瀏覽器類型、當前頁面的來源頁面,cookies等;

下面我們來看看一個標準的http請求頭後響應頭:

[[email protected] ~]# curl -v -I --referer http://baidu.com --user-agent
'Chrome/54.0 (Windows NT 10.0)' http://baidu.com/

* About to connect() to baidu.com port 80 (#0)

* Trying 180.149.132.47...

* Connected to baidu.com (180.149.132.47) port 80 (#0)

> HEAD / HTTP/1.1

> User-Agent: Chrome/54.0 (Windows NT 10.0)

> Host: baidu.com

> Accept: */*

> Referer: http://baidu.com

>

< HTTP/1.1 302 Moved Temporarily

HTTP/1.1 302 Moved Temporarily

< Server: bfe/1.0.8.18

Server: bfe/1.0.8.18

< Date: Fri, 02 Dec 2016 03:46:11 GMT

Date: Fri, 02 Dec 2016 03:46:11 GMT

< Content-Type: text/html

Content-Type: text/html

< Content-Length: 161

Content-Length: 161

< Connection: Keep-Alive

Connection: Keep-Alive

< Location: https://www.baidu.com/

Location: https://www.baidu.com/

< Expires: Sat, 03 Dec 2016 03:46:11 GMT

Expires: Sat, 03 Dec 2016 03:46:11 GMT

< Cache-Control: max-age=86400

Cache-Control: max-age=86400

< Cache-Control: private

Cache-Control: private

<

* Connection #0 to host baidu.com left intact

-A (or --user-agent): 設置 "User-Agent" 字段.

-b (or --cookie): 設置 "Cookie" 字段.

-e (or --referer): 設置 "Referer" 字段.

上面輸出可以看到,第7行和第9行就是我們設置的瀏覽器類型字符串和流量來源頁面。而httpd服務端接收到了什麼呢?我們這裏以http服務段使用的是PHP爲例,在站點上做一個“test.php”做爲測試頁面,PHP的Referer、User-Agent存放在$_SERVER變量中,所以我們的“test.php”文件只需要兩行代碼:

test.php文件:

<?php

print_r($_SERVER);

測試返回:

[root@localhost tmp]# curl --referer http://baidu.com --user-agent
'Chrome/54.0 (Windows NT 10.0)' http://localhost.com/test.php

Array

(

[HTTP_USER_AGENT] => Chrome/54.0 (Windows NT 10.0)

[HTTP_HOST] => localhost.com

[HTTP_ACCEPT] => */*

[HTTP_REFERER] => http://baidu.com

[PATH] => /sbin:/usr/sbin:/bin:/usr/bin

...

[REQUEST_METHOD] => GET

...

[PHP_SELF] => /test.php

[REQUEST_TIME] => 1480651125

)

二、僞裝來路(referer):

什麼是來路?從A頁面點擊進入B頁面,那B頁面的來路就是A頁面的URL。僞裝來路十分簡單,有兩種方法:1、使用上面的“--referer”參數或“-e參數”;2、直接使用“-H”參數設置http頭,下面分別介紹兩種方法。

1、“-e/--referer”參數方式:

# 告訴http服務器,我是從qq.com來的

[[email protected] ~]# curl -e http://qq.com http://localhost.com/test.php
2>/dev/null|grep HTTP_REFERER

[HTTP_REFERER] => http://qq.com

# 告訴http服務器,我是從baidu.com搜"localhost"關鍵詞點進來的

[[email protected] ~]# curl --referer https://www.baidu.com/s?wd=localhost
http://localhost.com/test.php 2>/dev/null|grep HTTP_REFERER

[HTTP_REFERER] => https://www.baidu.com/s?wd=localhost

2、“-H”參數的方式:

# 告訴http服務器,我是從微博過來的

[root@localhost ~]# curl -H "Referer: http://weibo.com"
http://localhost.com/test.php 2>/dev/null|grep HTTP_REFERER

[HTTP_REFERER] => http://weibo.com

三、僞裝瀏覽器類型(User-Agent):

首先,我們先找到瀏覽器對應的“User-Agent”字符串。可以直接在Chrome中的“開發者工具”的“網絡”標籤查看http請求頭獲得;也可以在網上搜索獲得,如通過百度搜索“微信useragent”、“ie
useragent”、“chrome useragent”等。

獲得對應瀏覽器的“User-Agent”字符串後,同樣可以通過兩種方式告訴http服務器我用的瀏覽器類型:

1、“-A/--user-agent”參數方式:

# 告訴http服務器,我是通過微信內置瀏覽器訪問

[[email protected] ~]# UA='Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac
OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12A365 MicroMessenger/6.0
NetType/WIFI';

[[email protected] ~]# curl -A "$UA" http://localhost.com/test.php|grep
HTTP_USER_AGENT

[HTTP_USER_AGENT] => Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X)
AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12A365 MicroMessenger/6.0
NetType/WIFI

# 告訴http服務器,我是通過Chrome瀏覽器訪問

[[email protected] ~]# UA='Mozilla/5.0 (Windows NT 6.2; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36';

[[email protected] ~]# curl --user-agent "$UA"
http://localhost.com/test.php|grep HTTP_USER_AGENT

[HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.2; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36

2、“-H”參數方式:

# 告訴網站,我是百度蜘蛛爬取

[[email protected] ~]# UA="Mozilla/5.0 (compatible; Baiduspider/2.0;
+http://www.baidu.com/search/spider.html)";

[[email protected] ~]# curl -H "User-Agent: $UA"
http://localhost.com/a.php|grep HTTP_USER_AGENT

[HTTP_USER_AGENT] => Mozilla/5.0 (compatible; Baiduspider/2.0;
+http://www.baidu.com/search/spider.html)

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