Linux工具參考篇(網摘)

Linux工具參考篇html

原文出處:【Linux Tools Quick Tutorialjava

  • 1. gdb 調試利器
  • 2. ldd 查看程序依賴庫
  • 3. lsof 一切皆文件
  • 4. ps 進程查看器
  • 5. pstack 跟蹤進程棧
  • 6. strace 跟蹤進程中的系統調用
  • 7. ipcs 查詢進程間通訊狀態
  • 8. top linux下的任務管理器
  • 9. free 查詢可用內存
  • 10. vmstat 監視內存使用狀況
  • 11. iostat 監視I/O子系統
  • 12. sar 找出系統瓶頸的利器
  • 13. readelf elf文件格式分析
  • 14. objdump 二進制文件分析
  • 15. nm 目標文件格式分析
  • 16. size 查看程序內存映像大小
  • 17. wget 文件下載
  • 18. scp 跨機遠程拷貝
  • 19. crontab 定時任務

1. gdb 調試利器

GDB是一個由GNU開源組織發佈的、UNIX/LINUX操做系統下的、基於命令行的、功能強大的程序調試工具。 對於一名Linux下工做的c++程序員,gdb是必不可少的工具;mysql

1.1. 啓動gdb

對C/C++程序的調試,須要在編譯前就加上-g選項:linux

$g++ -g hello.cpp -o hello

調試可執行文件:ios

$gdb <program>

program也就是你的執行文件,通常在當前目錄下。c++

調試core文件(core是程序非法執行後core dump後產生的文件):程序員

$gdb <program> <core dump file>
$gdb program core.11127

調試服務程序:web

$gdb <program> <PID>
$gdb hello 11127

若是你的程序是一個服務程序,那麼你能夠指定這個服務程序運行時的進程ID。gdb會自動attach上去,並調試他。program應該在PATH環境變量中搜索獲得。redis

1.2. gdb交互命令

啓動gdb後,進入到交互模式,經過如下命令完成對程序的調試;注意高頻使用的命令通常都會有縮寫,熟練使用這些縮寫命令能提升調試的效率;算法

運行

  • run:簡記爲 r ,其做用是運行程序,當遇到斷點後,程序會在斷點處中止運行,等待用戶輸入下一步的命令。
  • continue (簡寫c ):繼續執行,到下一個斷點處(或運行結束)
  • next:(簡寫 n),單步跟蹤程序,當遇到函數調用時,也不進入此函數體;此命令同 step 的主要區別是,step 遇到用戶自定義的函數,將步進到函數中去運行,而 next 則直接調用函數,不會進入到函數體內。
  • step (簡寫s):單步調試若是有函數調用,則進入函數;與命令n不一樣,n是不進入調用的函數的
  • until:當你厭倦了在一個循環體內單步跟蹤時,這個命令能夠運行程序直到退出循環體。
  • until+行號: 運行至某行,不只僅用來跳出循環
  • finish: 運行程序,直到當前函數完成返回,並打印函數返回時的堆棧地址和返回值及參數值等信息。
  • call 函數(參數):調用程序中可見的函數,並傳遞「參數」,如:call gdb_test(55)
  • quit:簡記爲 q ,退出gdb

設置斷點

  • break n (簡寫b n):在第n行處設置斷點
    (能夠帶上代碼路徑和代碼名稱: b OAGUPDATE.cpp:578)
  • b fn1 if a>b:條件斷點設置
  • break func(break縮寫爲b):在函數func()的入口處設置斷點,如:break cb_button
  • delete 斷點號n:刪除第n個斷點
  • disable 斷點號n:暫停第n個斷點
  • enable 斷點號n:開啓第n個斷點
  • clear 行號n:清除第n行的斷點
  • info b (info breakpoints) :顯示當前程序的斷點設置狀況
  • delete breakpoints:清除全部斷點:

查看源代碼

  • list :簡記爲 l ,其做用就是列出程序的源代碼,默認每次顯示10行。
  • list 行號:將顯示當前文件以「行號」爲中心的先後10行代碼,如:list 12
  • list 函數名:將顯示「函數名」所在函數的源代碼,如:list main
  • list :不帶參數,將接着上一次 list 命令的,輸出下邊的內容。

打印表達式

  • print 表達式:簡記爲 p ,其中「表達式」能夠是任何當前正在被測試程序的有效表達式,好比當前正在調試C語言的程序,那麼「表達式」能夠是任何C語言的有效表達式,包括數字,變量甚至是函數調用。
  • print a:將顯示整數 a 的值
  • print ++a:將把 a 中的值加1,並顯示出來
  • print name:將顯示字符串 name 的值
  • print gdb_test(22):將以整數22做爲參數調用 gdb_test() 函數
  • print gdb_test(a):將以變量 a 做爲參數調用 gdb_test() 函數
  • display 表達式:在單步運行時將很是有用,使用display命令設置一個表達式後,它將在每次單步進行指令後,緊接着輸出被設置的表達式及值。如: display a
  • watch 表達式:設置一個監視點,一旦被監視的「表達式」的值改變,gdb將強行終止正在被調試的程序。如: watch a
  • whatis :查詢變量或函數
  • info function: 查詢函數
  • 擴展info locals: 顯示當前堆棧頁的全部變量

查詢運行信息

  • where/bt :當前運行的堆棧列表;
  • bt backtrace 顯示當前調用堆棧
  • up/down 改變堆棧顯示的深度
  • set args 參數:指定運行時的參數
  • show args:查看設置好的參數
  • info program: 來查看程序的是否在運行,進程號,被暫停的緣由。

分割窗口

  • layout:用於分割窗口,能夠一邊查看代碼,一邊測試:
  • layout src:顯示源代碼窗口
  • layout asm:顯示反彙編窗口
  • layout regs:顯示源代碼/反彙編和CPU寄存器窗口
  • layout split:顯示源代碼和反彙編窗口
  • Ctrl + L:刷新窗口

註解

交互模式下直接回車的做用是重複上一指令,對於單步調試很是方便;

1.3. 更強大的工具

cgdb

cgdb能夠看做gdb的界面加強版,用來替代gdb的 gdb -tui。cgdb主要功能是在調試時進行代碼的同步顯示,這無疑增長了調試的方便性,提升了調試效率。界面相似vi,符合unix/linux下開發人員習慣;若是熟悉gdb和vi,幾乎能夠當即使用cgdb。

2. ldd 查看程序依賴庫

ldd
做用:用來查看程式運行所需的共享庫,經常使用來解決程式因缺乏某個庫文件而不能運行的一些問題。

示例:查看test程序運行所依賴的庫:

/opt/app/todeav1/test$ldd test
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00000039a7e00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003996400000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000039a5600000)
libc.so.6 => /lib64/libc.so.6 (0x0000003995800000)
/lib64/ld-linux-x86-64.so.2 (0x0000003995400000)
  • 第一列:程序須要依賴什麼庫
  • 第二列: 系統提供的與程序須要的庫所對應的庫
  • 第三列:庫加載的開始地址

經過上面的信息,咱們能夠獲得如下幾個信息:

  1. 經過對比第一列和第二列,咱們能夠分析程序須要依賴的庫和系統實際提供的,是否相匹配
  2. 經過觀察第三列,咱們能夠知道在當前的庫中的符號在對應的進程的地址空間中的開始位置

若是依賴的某個庫找不到,經過這個命令能夠迅速定位問題所在;

註解

原理: ldd不是個可執行程式,而只是個shell腳本; ldd顯示可執行模塊的dependency的工做原理,其實質是經過ld-linux.so(elf動態庫的裝載器)來實現的。ld-linux.so模塊會先於executable模塊程式工做,並得到控制權,所以當上述的那些環境變量被設置時,ld-linux.so選擇了顯示可執行模塊的dependency。

3. lsof 一切皆文件

lsof(list open files)是一個查看當前系統文件的工具。在linux環境下,任何事物都以文件的形式存在,經過文件不只僅能夠訪問常規數據,還能夠訪問網絡鏈接和硬件。如傳輸控制協議 (TCP) 和用戶數據報協議 (UDP) 套接字等,系統在後臺都爲該應用程序分配了一個文件描述符,該文件描述符提供了大量關於這個應用程序自己的信息。

lsof打開的文件能夠是:

  1. 普通文件
  2. 目錄
  3. 網絡文件系統的文件
  4. 字符或設備文件
  5. (函數)共享庫
  6. 管道,命名管道
  7. 符號連接
  8. 網絡文件(例如:NFS file、網絡socket,unix域名socket)
  9. 還有其它類型的文件,等等

3.1. 命令參數

  • -a 列出打開文件存在的進程
  • -c<進程名> 列出指定進程所打開的文件
  • -g 列出GID號進程詳情
  • -d<文件號> 列出佔用該文件號的進程
  • +d<目錄> 列出目錄下被打開的文件
  • +D<目錄> 遞歸列出目錄下被打開的文件
  • -n<目錄> 列出使用NFS的文件
  • -i<條件> 列出符合條件的進程。(四、六、協議、:端口、 @ip )
  • -p<進程號> 列出指定進程號所打開的文件
  • -u 列出UID號進程詳情
  • -h 顯示幫助信息
  • -v 顯示版本信息

3.2. 使用實例

實例1:無任何參數

$lsof| more
COMMAND     PID      USER   FD      TYPE             DEVICE SIZE/OFF       NODE NAME
init          1      root  cwd       DIR              253,0     4096          2 /
init          1      root  rtd       DIR              253,0     4096          2 /
init          1      root  txt       REG              253,0   150352    1310795 /sbin/init
init          1      root  mem       REG              253,0    65928    5505054 /lib64/libnss_files-2.12.so
init          1      root  mem       REG              253,0  1918016    5521405 /lib64/libc-2.12.so
init          1      root  mem       REG              253,0    93224    5521440 /lib64/libgcc_s-4.4.6-20120305.so.1
init          1      root  mem       REG              253,0    47064    5521407 /lib64/librt-2.12.so
init          1      root  mem       REG              253,0   145720    5521406 /lib64/libpthread-2.12.so
...

說明:

lsof輸出各列信息的意義以下:

  • COMMAND:進程的名稱

  • PID:進程標識符

  • PPID:父進程標識符(須要指定-R參數)

  • USER:進程全部者

  • PGID:進程所屬組

  • FD:文件描述符,應用程序經過文件描述符識別該文件。如cwd、txt等:

    (1)cwd:表示current work dirctory,即:應用程序的當前工做目錄,這是該應用程序啓動的目錄,除非它自己對這個目錄進行更改
    (2)txt :該類型的文件是程序代碼,如應用程序二進制文件自己或共享庫,如上列表中顯示的 /sbin/init 程序
    (3)lnn:library references (AIX);
    (4)er:FD information error (see NAME column);
    (5)jld:jail directory (FreeBSD);
    (6)ltx:shared library text (code and data);
    (7)mxx :hex memory-mapped type number xx.
    (8)m86:DOS Merge mapped file;
    (9)mem:memory-mapped file;
    (10)mmap:memory-mapped device;
    (11)pd:parent directory;
    (12)rtd:root directory;
    (13)tr:kernel trace file (OpenBSD);
    (14)v86  VP/ix mapped file;
    (15)0:表示標準輸入
    (16)1:表示標準輸出
    (17)2:表示標準錯誤
    通常在標準輸出、標準錯誤、標準輸入後還跟着文件狀態模式:r、w、u等
    (1)u:表示該文件被打開並處於讀取/寫入模式
    (2)r:表示該文件被打開並處於只讀模式
    (3)w:表示該文件被打開並處於
    (4)空格:表示該文件的狀態模式爲unknow,且沒有鎖定
    (5)-:表示該文件的狀態模式爲unknow,且被鎖定
    同時在文件狀態模式後面,還跟着相關的鎖
    (1)N:for a Solaris NFS lock of unknown type;
    (2)r:for read lock on part of the file;
    (3)R:for a read lock on the entire file;
    (4)w:for a write lock on part of the file;(文件的部分寫鎖)
    (5)W:for a write lock on the entire file;(整個文件的寫鎖)
    (6)u:for a read and write lock of any length;
    (7)U:for a lock of unknown type;
    (8)x:for an SCO OpenServer Xenix lock on part      of the file;
    (9)X:for an SCO OpenServer Xenix lock on the      entire file;
    (10)space:if there is no lock.
    
  • TYPE:文件類型,如DIR、REG等,常見的文件類型:

    (1)DIR:表示目錄
    (2)CHR:表示字符類型
    (3)BLK:塊設備類型
    (4)UNIX: UNIX 域套接字
    (5)FIFO:先進先出 (FIFO) 隊列
    (6)IPv4:網際協議 (IP) 套接字
    
  • DEVICE:指定磁盤的名稱

  • SIZE:文件的大小

  • NODE:索引節點(文件在磁盤上的標識)

  • NAME:打開文件的確切名稱

實例2:查找某個文件相關的進程

$lsof /bin/bash
COMMAND     PID USER  FD   TYPE DEVICE SIZE/OFF    NODE NAME
mysqld_sa  2169 root txt    REG  253,0   938736 4587562 /bin/bash
ksmtuned   2334 root txt    REG  253,0   938736 4587562 /bin/bash
bash      20121 root txt    REG  253,0   938736 4587562 /bin/bash

實例3:列出某個用戶打開的文件信息

$lsof -u username

-u 選項,u是user的縮寫

實例4:列出某個程序進程所打開的文件信息

$lsof -c mysql

-c 選項將會列出全部以mysql這個進程開頭的程序的文件,其實你也能夠寫成 lsof | grep mysql, 可是第一種方法明顯比第二種方法要少打幾個字符;

實例5:列出某個用戶以及某個進程所打開的文件信息

$lsof  -u test -c mysql

實例6:經過某個進程號顯示該進程打開的文件

$lsof -p 11968

實例7:列出全部的網絡鏈接

$lsof -i

實例8:列出全部tcp 網絡鏈接信息

$lsof -i tcp

$lsof -n -i tcp
COMMAND     PID  USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
svnserve  11552 weber    3u  IPv4 3799399      0t0  TCP *:svn (LISTEN)
redis-ser 25501 weber    4u  IPv4  113150      0t0  TCP 127.0.0.1:6379 (LISTEN)

實例9:列出誰在使用某個端口

$lsof -i :3306

實例10:列出某個用戶的全部活躍的網絡端口

$lsof -a -u test -i

實例11:根據文件描述列出對應的文件信息

$lsof -d description(like 2)

示例:

$lsof -d 3 | grep PARSER1
tail      6499 tde    3r   REG    253,3   4514722     417798 /opt/applog/open/log/HOSTPARSER1_ERROR_141217.log.001

說明: 0表示標準輸入,1表示標準輸出,2表示標準錯誤,從而可知:因此大多數應用程序所打開的文件的 FD 都是從 3 開始

實例12:列出被進程號爲1234的進程所打開的全部IPV4 network files

$lsof -i 4 -a -p 1234

實例13:列出目前鏈接主機nf5260i5-td上端口爲:20,21,80相關的全部文件信息,且每隔3秒重複執行

lsof -i @nf5260i5-td:20,21,80 -r 3

4. ps 進程查看器

Linux中的ps命令是Process Status的縮寫。ps命令用來列出系統中當前運行的那些進程。ps命令列出的是當前那些進程的快照,就是執行ps命令的那個時刻的那些進程,若是想要動態的顯示進程信息,就可使用top命令。

要對進程進行監測和控制,首先必需要了解當前進程的狀況,也就是須要查看當前進程,而 ps 命令就是最基本同時也是很是強大的進程查看命令。使用該命令能夠肯定有哪些進程正在運行和運行的狀態、進程是否結束、進程有沒有僵死、哪些進程佔用了過多的資源等等。總之大部分信息都是能夠經過執行該命令獲得的。

ps 爲咱們提供了進程的一次性的查看,它所提供的查看結果並不動態連續的;若是想對進程時間監控,應該用 top linux下的任務管理器 工具。

注:kill 命令用於殺死進程。

linux上進程有5種狀態:

  1. 運行(正在運行或在運行隊列中等待)
  2. 中斷(休眠中, 受阻, 在等待某個條件的造成或接受到信號)
  3. 不可中斷(收到信號不喚醒和不可運行, 進程必須等待直到有中斷髮生)
  4. 僵死(進程已終止, 但進程描述符存在, 直到父進程調用wait4()系統調用後釋放)
  5. 中止(進程收到SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU信號後中止運行運行)

ps工具標識進程的5種狀態碼:

  • D 不可中斷 uninterruptible sleep (usually IO)
  • R 運行 runnable (on run queue)
  • S 中斷 sleeping
  • T 中止 traced or stopped
  • Z 僵死 a defunct (」zombie」) process

4.1. 命令參數

  • a 顯示全部進程
  • -a 顯示同一終端下的全部程序
  • -A 顯示全部進程
  • c 顯示進程的真實名稱
  • -N 反向選擇
  • -e 等於「-A」
  • e 顯示環境變量
  • f 顯示程序間的關係
  • -H 顯示樹狀結構
  • r 顯示當前終端的進程
  • T 顯示當前終端的全部程序
  • u 指定用戶的全部進程
  • -au 顯示較詳細的資訊
  • -aux 顯示全部包含其餘使用者的行程
  • -C<命令> 列出指定命令的情況
  • –lines<行數> 每頁顯示的行數
  • –width<字符數> 每頁顯示的字符數
  • –help 顯示幫助信息
  • –version 顯示版本顯示

4.2. 輸出列的含義

  • F 表明這個程序的旗標 (flag), 4 表明使用者爲 super user
  • S 表明這個程序的狀態 (STAT),關於各 STAT 的意義將在內文介紹
  • UID 程序被該 UID 所擁有
  • PID 進程的ID
  • PPID 則是其上級父程序的ID
  • C CPU 使用的資源百分比
  • PRI 這個是 Priority (優先執行序) 的縮寫,詳細後面介紹
  • NI 這個是 Nice 值,在下一小節咱們會持續介紹
  • ADDR 這個是 kernel function,指出該程序在內存的那個部分。若是是個 running的程序,通常就是 「-「
  • SZ 使用掉的內存大小
  • WCHAN 目前這個程序是否正在運做當中,若爲 - 表示正在運做
  • TTY 登入者的終端機位置
  • TIME 使用掉的 CPU 時間。
  • CMD 所下達的指令爲什麼

4.3. 使用實例

實例1:顯示全部進程信息

[root@localhost test6]# ps -A
PID TTY          TIME CMD
1 ?        00:00:00 init
2 ?        00:00:01 migration/0
3 ?        00:00:00 ksoftirqd/0
4 ?        00:00:01 migration/1
5 ?        00:00:00 ksoftirqd/1
6 ?        00:29:57 events/0
7 ?        00:00:00 events/1
8 ?        00:00:00 khelper
49 ?        00:00:00 kthread
54 ?        00:00:00 kblockd/0
55 ?        00:00:00 kblockd/1
56 ?        00:00:00 kacpid
217 ?        00:00:00 cqueue/0
……省略部分結果

實例2:顯示指定用戶信息

[root@localhost test6]# ps -u root
PID TTY          TIME CMD
1 ?        00:00:00 init
2 ?        00:00:01 migration/0
3 ?        00:00:00 ksoftirqd/0
4 ?        00:00:01 migration/1
5 ?        00:00:00 ksoftirqd/1
6 ?        00:29:57 events/0
7 ?        00:00:00 events/1
8 ?        00:00:00 khelper
49 ?        00:00:00 kthread
54 ?        00:00:00 kblockd/0
55 ?        00:00:00 kblockd/1
56 ?        00:00:00 kacpid
……省略部分結果

實例3:顯示全部進程信息,連同命令行

[root@localhost test6]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Nov02 ?        00:00:00 init [3]
root         2     1  0 Nov02 ?        00:00:01 [migration/0]
root         3     1  0 Nov02 ?        00:00:00 [ksoftirqd/0]
root         4     1  0 Nov02 ?        00:00:01 [migration/1]
root         5     1  0 Nov02 ?        00:00:00 [ksoftirqd/1]
root         6     1  0 Nov02 ?        00:29:57 [events/0]
root         7     1  0 Nov02 ?        00:00:00 [events/1]
root         8     1  0 Nov02 ?        00:00:00 [khelper]
root        49     1  0 Nov02 ?        00:00:00 [kthread]
root        54    49  0 Nov02 ?        00:00:00 [kblockd/0]
root        55    49  0 Nov02 ?        00:00:00 [kblockd/1]
root        56    49  0 Nov02 ?        00:00:00 [kacpid]

實例4: ps 與grep 組合使用,查找特定進程

[root@localhost test6]# ps -ef|grep ssh
root      2720     1  0 Nov02 ?        00:00:00 /usr/sbin/sshd
root     17394  2720  0 14:58 ?        00:00:00 sshd: root@pts/0
root     17465 17398  0 15:57 pts/0    00:00:00 grep ssh

實例5:將與此次登入的 PID 與相關信息列示出來

[root@localhost test6]# ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 17398 17394  0  75   0 - 16543 wait   pts/0    00:00:00 bash
4 R     0 17469 17398  0  77   0 - 15877 -      pts/0    00:00:00 ps

實例6:列出目前全部的正在內存中的程序

[root@localhost test6]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  10368   676 ?        Ss   Nov02   0:00 init [3]
root         2  0.0  0.0      0     0 ?        S<   Nov02   0:01 [migration/0]
root         3  0.0  0.0      0     0 ?        SN   Nov02   0:00 [ksoftirqd/0]
root         4  0.0  0.0      0     0 ?        S<   Nov02   0:01 [migration/1]
root         5  0.0  0.0      0     0 ?        SN   Nov02   0:00 [ksoftirqd/1]
root         6  0.0  0.0      0     0 ?        S<   Nov02  29:57 [events/0]
root         7  0.0  0.0      0     0 ?        S<   Nov02   0:00 [events/1]
root         8  0.0  0.0      0     0 ?        S<   Nov02   0:00 [khelper]
root        49  0.0  0.0      0     0 ?        S<   Nov02   0:00 [kthread]
root        54  0.0  0.0      0     0 ?        S<   Nov02   0:00 [kblockd/0]
root        55  0.0  0.0      0     0 ?        S<   Nov02   0:00 [kblockd/1]
root        56  0.0  0.0      0     0 ?        S<   Nov02   0:00 [kacpid]

5. pstack 跟蹤進程棧

此命令可顯示每一個進程的棧跟蹤。pstack 命令必須由相應進程的屬主或 root 運行。可使用 pstack 來肯定進程掛起的位置。此命令容許使用的惟一選項是要檢查的進程的 PID。請參見 proc(1) 手冊頁。

這個命令在排查進程問題時很是有用,好比咱們發現一個服務一直處於work狀態(如假死狀態,好似死循環),使用這個命令就能輕鬆定位問題所在;能夠在一段時間內,多執行幾回pstack,若發現代碼棧老是停在同一個位置,那個位置就須要重點關注,極可能就是出問題的地方;

示例:查看bash程序進程棧:

/opt/app/tdev1$ps -fe| grep bash
tdev1   7013  7012  0 19:42 pts/1    00:00:00 -bash
tdev1  11402 11401  0 20:31 pts/2    00:00:00 -bash
tdev1  11474 11402  0 20:32 pts/2    00:00:00 grep bash
/opt/app/tdev1$pstack 7013
#0  0x00000039958c5620 in __read_nocancel () from /lib64/libc.so.6
#1  0x000000000047dafe in rl_getc ()
#2  0x000000000047def6 in rl_read_key ()
#3  0x000000000046d0f5 in readline_internal_char ()
#4  0x000000000046d4e5 in readline ()
#5  0x00000000004213cf in ?? ()
#6  0x000000000041d685 in ?? ()
#7  0x000000000041e89e in ?? ()
#8  0x00000000004218dc in yyparse ()
#9  0x000000000041b507 in parse_command ()
#10 0x000000000041b5c6 in read_command ()
#11 0x000000000041b74e in reader_loop ()
#12 0x000000000041b2aa in main ()

6. strace 跟蹤進程中的系統調用

strace經常使用來跟蹤進程執行時的系統調用和所接收的信號。 在Linux世界,進程不能直接訪問硬件設備,當進程須要訪問硬件設備(好比讀取磁盤文件,接收網絡數據等等)時,必須由用戶態模式切換至內核態模式,經過系統調用訪問硬件設備。strace能夠跟蹤到一個進程產生的系統調用,包括參數,返回值,執行消耗的時間。

6.1. 輸出參數含義

每一行都是一條系統調用,等號左邊是系統調用的函數名及其參數,右邊是該調用的返回值。 strace 顯示這些調用的參數並返回符號形式的值。strace 從內核接收信息,並且不須要以任何特殊的方式來構建內核。

$strace cat /dev/null
execve("/bin/cat", ["cat", "/dev/null"], [/* 22 vars */]) = 0
brk(0)                                  = 0xab1000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29379a7000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
...

6.2. 參數

-c 統計每一系統調用的所執行的時間,次數和出錯的次數等.
-d 輸出strace關於標準錯誤的調試信息.
-f 跟蹤由fork調用所產生的子進程.
-ff 若是提供-o filename,則全部進程的跟蹤結果輸出到相應的filename.pid中,pid是各進程的進程號.
-F 嘗試跟蹤vfork調用.在-f時,vfork不被跟蹤.
-h 輸出簡要的幫助信息.
-i 輸出系統調用的入口指針.
-q 禁止輸出關於脫離的消息.
-r 打印出相對時間關於,,每個系統調用.
-t 在輸出中的每一行前加上時間信息.
-tt 在輸出中的每一行前加上時間信息,微秒級.
-ttt 微秒級輸出,以秒了表示時間.
-T 顯示每一調用所耗的時間.
-v 輸出全部的系統調用.一些調用關於環境變量,狀態,輸入輸出等調用因爲使用頻繁,默認不輸出.
-V 輸出strace的版本信息.
-x 以十六進制形式輸出非標準字符串
-xx 全部字符串以十六進制形式輸出.
-a column
設置返回值的輸出位置.默認 爲40.
-e expr
指定一個表達式,用來控制如何跟蹤.格式以下:
[qualifier=][!]value1[,value2]...
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用來限定的符號或數字.默認的 qualifier是 trace.感嘆號是否認符號.例如:
-eopen等價於 -e trace=open,表示只跟蹤open調用.而-etrace!=open表示跟蹤除了open之外的其餘調用.有兩個特殊的符號 all 和 none.
注意有些shell使用!來執行歷史記錄裏的命令,因此要使用\\.
-e trace=set
只跟蹤指定的系統 調用.例如:-e trace=open,close,rean,write表示只跟蹤這四個系統調用.默認的爲set=all.
-e trace=file
只跟蹤有關文件操做的系統調用.
-e trace=process
只跟蹤有關進程控制的系統調用.
-e trace=network
跟蹤與網絡有關的全部系統調用.
-e strace=signal
跟蹤全部與系統信號有關的 系統調用
-e trace=ipc
跟蹤全部與進程通信有關的系統調用
-e abbrev=set
設定 strace輸出的系統調用的結果集.-v 等與 abbrev=none.默認爲abbrev=all.
-e raw=set
將指 定的系統調用的參數以十六進制顯示.
-e signal=set
指定跟蹤的系統信號.默認爲all.如 signal=!SIGIO(或者signal=!io),表示不跟蹤SIGIO信號.
-e read=set
輸出從指定文件中讀出 的數據.例如:
-e read=3,5
-e write=set
輸出寫入到指定文件中的數據.
-o filename
將strace的輸出寫入文件filename
-p pid
跟蹤指定的進程pid.
-s strsize
指定輸出的字符串的最大長度.默認爲32.文件名一直所有輸出.
-u username
以username 的UID和GID執行被跟蹤的命令

6.3. 命令實例

跟蹤可執行程序

strace -f -F -o ~/straceout.txt myserver

-f -F選項告訴strace同時跟蹤fork和vfork出來的進程,-o選項把全部strace輸出寫到~/straceout.txt裏 面,myserver是要啓動和調試的程序。

跟蹤服務程序

strace -o output.txt -T -tt -e trace=all -p 28979

跟蹤28979進程的全部系統調用(-e trace=all),並統計系統調用的花費時間,以及開始時間(並以可視化的時分秒格式顯示),最後將記錄結果存在output.txt文件裏面。

7. ipcs 查詢進程間通訊狀態

ipcs是Linux下顯示進程間通訊設施狀態的工具。能夠顯示消息隊列、共享內存和信號量的信息。對於程序員很是有用,普通的系統管理員通常用不到此指令。

7.1. IPC資源查詢

查看系統使用的IPC資源

$ipcs

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status

------ Semaphore Arrays --------
key        semid      owner      perms      nsems
0x00000000 229376     weber      600        1

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages

分別查詢IPC資源:

$ipcs -m 查看系統使用的IPC共享內存資源
$ipcs -q 查看系統使用的IPC隊列資源
$ipcs -s 查看系統使用的IPC信號量資源

查看IPC資源被誰佔用

示例:有個IPCKEY(51036),須要查詢其是否被佔用;

  1. 首先經過計算器將其轉爲十六進制:

    51036 -> c75c
  2. 若是知道是被共享內存佔用:

    $ipcs -m | grep c75c
    0x0000c75c 40403197   tdea3    666        536870912  2
  3. 若是不肯定,則直接查找:

    $ipcs | grep c75c
    0x0000c75c 40403197   tdea3    666        536870912  2
    0x0000c75c 5079070    tdea3    666        4

7.2. 系統IPC參數查詢

ipcs -l

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 4194303
max total shared memory (kbytes) = 1073741824
min seg size (bytes) = 1

------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767

------ Messages: Limits --------
max queues system wide = 2048
max size of message (bytes) = 524288
default max size of queue (bytes) = 5242880

以上輸出顯示,目前這個系統的容許的最大內存爲1073741824kb;最大可以使用128個信號量,每一個消息的最大長度爲524288bytes;

7.3. 修改IPC系統參數

以linux系統爲例,在root用戶下修改/etc/sysctl.conf 文件,保存後使用sysctl -p生效:

$cat /etc/sysctl.conf
# 一個消息的最大長度
kernel.msgmax = 524288

# 一個消息隊列上的最大字節數
# 524288*10
kernel.msgmnb = 5242880

#最大消息隊列的個數
kernel.msgmni=2048

#一個共享內存區的最大字節數
kernel.shmmax = 17179869184

#系統範圍內最大共享內存標識數
kernel.shmmni=4096

#每一個信號燈集的最大信號燈數 系統範圍內最大信號燈數 每一個信號燈支持的最大操做數 系統範圍內最大信號燈集數
#此參數爲系統默認,能夠不用修改
#kernel.sem = <semmsl> <semmni>*<semmsl> <semopm> <semmni>
kernel.sem = 250 32000 32 128

顯示輸入不帶標誌的 ipcs:的輸出:

$ipcs
IPC status from /dev/mem as of Mon Aug 14 15:03:46 1989
T    ID         KEY        MODE       OWNER     GROUP
Message Queues:
q       0    0x00010381 -Rrw-rw-rw-   root      system
q   65537    0x00010307 -Rrw-rw-rw-   root      system
q   65538    0x00010311 -Rrw-rw-rw-   root      system
q   65539    0x0001032f -Rrw-rw-rw-   root      system
q   65540    0x0001031b -Rrw-rw-rw-   root      system
q   65541    0x00010339--rw-rw-rw-    root      system
q       6    0x0002fe03 -Rrw-rw-rw-   root      system
Shared Memory:
m   65537    0x00000000 DCrw-------   root      system
m  720898    0x00010300 -Crw-rw-rw-   root      system
m   65539    0x00000000 DCrw-------   root      system
Semaphores:
s  131072    0x4d02086a --ra-ra----   root      system
s   65537    0x00000000 --ra-------   root      system
s 1310722    0x000133d0 --ra-------   7003      30720

7.4. 清除IPC資源

使用ipcrm 命令來清除IPC資源:這個命令同時會將與ipc對象相關聯的數據也一塊兒移除。固然,只有root用戶,或者ipc對象的建立者纔有這項權利;

ipcrm用法:

ipcrm -M shmkey  移除用shmkey建立的共享內存段
ipcrm -m shmid    移除用shmid標識的共享內存段
ipcrm -Q msgkey  移除用msqkey建立的消息隊列
ipcrm -q msqid  移除用msqid標識的消息隊列
ipcrm -S semkey  移除用semkey建立的信號
ipcrm -s semid  移除用semid標識的信號

清除當前用戶建立的全部的IPC資源:

ipcs -q | awk '{ print "ipcrm -q "$2}' | sh > /dev/null 2>&1;
ipcs -m | awk '{ print "ipcrm -m "$2}' | sh > /dev/null 2>&1;
ipcs -s | awk '{ print "ipcrm -s "$2}' | sh > /dev/null 2>&1;

7.5. 綜合應用

查詢user1用戶環境上是否存在積Queue現象

  1. 查詢隊列Queue:

    $ipcs -q
    
    ------ Message Queues --------
    key        msqid      owner      perms      used-bytes   messages
    0x49060005 58261504   user1    660        0            0
    0x4f060005 58294273   user1    660        0            0
    ...
  2. 找出第6列大於0的服務:

    $ ipcs -q |grep user1 |awk '{if($5>0) print $0}'
    0x00000000 1071579324 user1       644        1954530      4826
    0x00000000 1071644862 user1       644        1961820      4844
    0x00000000 1071677631 user1       644        1944810      4802
    0x00000000 1071710400 user1       644        1961820      4844

8. top linux下的任務管理器

top命令是Linux下經常使用的性能分析工具,可以實時顯示系統中各個進程的資源佔用情況,相似於Windows的任務管理器。top是一個動態顯示過程,便可以經過用戶按鍵來不斷刷新當前狀態.若是在前臺執行該命令,它將獨佔前臺,直到用戶終止該程序爲止.比較準確的說,top命令提供了實時的對系統處理器的狀態監視.它將顯示系統中CPU最「敏感」的任務列表.該命令能夠按CPU使用.內存使用和執行時間對任務進行排序;並且該命令的不少特性均可以經過交互式命令或者在我的定製文件中進行設定。

$top
    top - 09:14:56 up 264 days, 20:56,  1 user,  load average: 0.02, 0.04, 0.00
    Tasks:  87 total,   1 running,  86 sleeping,   0 stopped,   0 zombie
    Cpu(s):  0.0%us,  0.2%sy,  0.0%ni, 99.7%id,  0.0%wa,  0.0%hi,  0.0%si,  0.2%st
    Mem:    377672k total,   322332k used,    55340k free,    32592k buffers
    Swap:   397308k total,    67192k used,   330116k free,    71900k cached
    PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    1 root      20   0  2856  656  388 S  0.0  0.2   0:49.40 init
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd
    3 root      20   0     0    0    0 S  0.0  0.0   7:15.20 ksoftirqd/0
    4 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0
  • 第一行
    • 09:14:56 : 系統當前時間
    • 264 days, 20:56 : 系統開機到如今通過了多少時間
    • 1 users : 當前2用戶在線
    • load average: 0.02, 0.04, 0.00: 系統1分鐘、5分鐘、15分鐘的CPU負載信息
  • 第二行
    • Tasks:任務;
    • 87 total:很好理解,就是當前有87個任務,也就是87個進程。
    • 1 running:1個進程正在運行
    • 86 sleeping:86個進程睡眠
    • 0 stopped:中止的進程數
    • 0 zombie:僵死的進程數
  • 第三行
    • Cpu(s):表示這一行顯示CPU整體信息
    • 0.0%us:用戶態進程佔用CPU時間百分比,不包含renice值爲負的任務佔用的CPU的時間。
    • 0.7%sy:內核佔用CPU時間百分比
    • 0.0%ni:改變過優先級的進程佔用CPU的百分比
    • 99.3%id:空閒CPU時間百分比
    • 0.0%wa:等待I/O的CPU時間百分比
    • 0.0%hi:CPU硬中斷時間百分比
    • 0.0%si:CPU軟中斷時間百分比
    • 注:這裏顯示數據是全部cpu的平均值,若是想看每個cpu的處理狀況,按1便可;摺疊,再次按1;
  • 第四行
    • Men:內存的意思
    • 8175320kk total:物理內存總量
    • 8058868k used:使用的物理內存量
    • 116452k free:空閒的物理內存量
    • 283084k buffers:用做內核緩存的物理內存量
  • 第五行
    • Swap:交換空間
    • 6881272k total:交換區總量
    • 4010444k used:使用的交換區量
    • 2870828k free:空閒的交換區量
    • 4336992k cached:緩衝交換區總量
  • 進程信息
    • 再下面就是進程信息:
    • PID:進程的ID
    • USER:進程全部者
    • PR:進程的優先級別,越小越優先被執行
    • NInice:值
    • VIRT:進程佔用的虛擬內存
    • RES:進程佔用的物理內存
    • SHR:進程使用的共享內存
    • S:進程的狀態。S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值爲負數
    • %CPU:進程佔用CPU的使用率
    • %MEM:進程使用的物理內存和總內存的百分比
    • TIME+:該進程啓動後佔用的總的CPU時間,即佔用CPU使用時間的累加值。
    • COMMAND:進程啓動命令名稱

8.1. top命令交互操做指令

下面列出一些經常使用的 top命令操做指令

  • q:退出top命令
  • <Space>:當即刷新
  • s:設置刷新時間間隔
  • c:顯示命令徹底模式
  • t::顯示或隱藏進程和CPU狀態信息
  • m:顯示或隱藏內存狀態信息
  • l:顯示或隱藏uptime信息
  • f:增長或減小進程顯示標誌
  • S:累計模式,會把已完成或退出的子進程佔用的CPU時間累計到父進程的MITE+
  • P:按%CPU使用率排行
  • T:按MITE+排行
  • M:按%MEM排行
  • u:指定顯示用戶進程
  • r:修改進程renice值
  • kkill:進程
  • i:只顯示正在運行的進程
  • W:保存對top的設置到文件^/.toprc,下次啓動將自動調用toprc文件的設置。
  • h:幫助命令。
  • q:退出

注:強調一下,使用頻率最高的是P、T、M,由於一般使用top,咱們就想看看是哪些進程最耗cpu資源、佔用的內存最多; 注:經過」shift + >」或」shift + <」能夠向右或左改變排序列 若是隻須要查看內存:可用free命令。只查看uptime信息(第一行),可用uptime命令;

8.2. 實例

實例1:多核CPU監控

在top基本視圖中,按鍵盤數字「1」,可監控每一個邏輯CPU的情況;

[rdtfr@bl685cb4-t ^]$ top
top - 09:10:44 up 20 days, 16:51,  4 users,  load average: 3.82, 4.40, 4.40
Tasks: 1201 total,  10 running, 1189 sleeping,   0 stopped,   2 zombie
Cpu0  :  1.3%us,  2.3%sy,  0.0%ni, 96.4%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu1  :  1.3%us,  2.6%sy,  0.0%ni, 96.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  :  1.0%us,  2.0%sy,  0.0%ni, 92.5%id,  0.0%wa,  0.0%hi,  4.6%si,  0.0%st
Cpu3  :  3.9%us,  7.8%sy,  0.0%ni, 83.2%id,  0.0%wa,  0.0%hi,  5.2%si,  0.0%st
Cpu4  :  4.2%us, 10.4%sy,  0.0%ni, 63.8%id,  0.0%wa,  0.0%hi, 21.5%si,  0.0%st
Cpu5  :  6.8%us, 12.7%sy,  0.0%ni, 80.5%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu6  :  2.9%us,  7.2%sy,  0.0%ni, 85.3%id,  0.0%wa,  0.0%hi,  4.6%si,  0.0%st
Cpu7  :  6.2%us, 13.0%sy,  0.0%ni, 75.3%id,  0.0%wa,  0.0%hi,  5.5%si,  0.0%st
Mem:  32943888k total, 32834216k used,   109672k free,   642704k buffers
Swap: 35651576k total,  5761928k used, 29889648k free, 16611500k cached

實例2:高亮顯示當前運行進程

在top基本視圖中,按鍵盤「b」(打開/關閉加亮效果);

實例3:顯示完整的程序命令

命令:top -c

[rdtfr@bl685cb4-t ^]$ top -c
top - 09:14:35 up 20 days, 16:55,  4 users,  load average: 5.77, 5.01, 4.64
Tasks: 1200 total,   5 running, 1192 sleeping,   0 stopped,   3 zombie
Cpu(s):  4.4%us,  6.0%sy,  0.0%ni, 83.8%id,  0.2%wa,  0.0%hi,  5.5%si,  0.0%st
Mem:  32943888k total, 32842896k used,   100992k free,   591484k buffers
Swap: 35651576k total,  5761808k used, 29889768k free, 16918824k cached
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
2013 apache    18   0  403m  88m 5304 S 25.0  0.3   6:37.44 /usr/sbin/httpd
18335 pubtest   22   0 65576  996  728 R  7.8  0.0   0:00.24 netstat -naltp
16499 rdtfare   15   0 13672 2080  824 R  2.6  0.0   0:00.38 top -c
29684 rdtfare   15   0 1164m 837m  14m S  2.3  2.6 148:47.54 ./autodata data1.txt
12976 pubtest   18   0  238m 9000 1932 S  1.6  0.0 439:28.44 tscagent -s TOEV_P

實例4:顯示指定的進程信息

命令:top -p pidid

/opt/app/tdv1/config#top -p 17265
top - 09:17:34 up 455 days, 17:55,  2 users,  load average: 3.76, 4.56, 4.46
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
Cpu(s):  7.8%us,  1.9%sy,  0.0%ni, 89.2%id,  0.0%wa,  0.1%hi,  1.0%si,  0.0%st
Mem:   8175452k total,  8103988k used,    71464k free,   268716k buffers
Swap:  6881272k total,  4275424k used,  2605848k free,  6338184k cached
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
17265 tdv1      15   0 56504  828  632 S  0.0  0.0 195:53.25 redis-server

指定進程信息有多個時,須要結合其它工具將回車替換爲,(-p 支持pid,pid,pid語法)

命令:top -p pgrep MULTI_PROCESS | tr 「\n」 」,」 | sed ‘s/,$//’

/opt/app/tdv1$top -p `pgrep java | tr "\\n" "," | sed 's/,$//'`
top - 14:05:31 up 53 days,  2:43,  9 users,  load average: 0.29, 0.34, 0.22
Tasks:   3 total,   0 running,   3 sleeping,   0 stopped,   0 zombie
Cpu(s):  5.9%us,  8.2%sy,  0.0%ni, 86.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  66082088k total, 29512860k used, 36569228k free,   756352k buffers
Swap: 32767992k total,  1019900k used, 31748092k free, 15710284k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND  27855 rdtfare   20   0 4454m 1.3g 5300 S  0.7  2.0 338:31.37 java
 2034 jenkins   20   0 18.3g 5.2g 5284 S  0.3  8.2  56:02.38 java     12156 rdtfare   20   0 4196m 1.2g  12m S  0.3  2.0  86:34.62 java

8.3. 更強大的工具

htop

htop 是一個 Linux 下的交互式的進程瀏覽器,能夠用來替換Linux下的top命令。

與Linux傳統的top相比,htop更加人性化。它可以讓用戶交互式操做,支持顏色主題,可橫向或縱向滾動瀏覽進程列表,並支持鼠標操做。

與top相比,htop有如下優勢:

  • 能夠橫向或縱向滾動瀏覽進程列表,以便看到全部的進程和完整的命令行。
  • 在啓動上,比top 更快。
  • 殺進程時不須要輸入進程號。
  • htop 支持鼠標操做。

9. free 查詢可用內存

free工具用來查看系統可用內存:

/opt/app/tdev1$free
             total       used       free     shared    buffers     cached
Mem:       8175320    6159248    2016072          0     310208    5243680
-/+ buffers/cache:     605360    7569960
Swap:      6881272      16196    6865076

解釋一下Linux上free命令的輸出。

下面是free的運行結果,一共有4行。爲了方便說明,我加上了列號。這樣能夠把free的輸出當作一個二維數組FO(Free Output)。例如:

FO[2][1] = 24677460
FO[3][2] = 10321516

                   1          2          3          4          5          6
1              total       used       free     shared    buffers     cached
2 Mem:      24677460   23276064    1401396          0     870540   12084008
3 -/+ buffers/cache:   10321516   14355944
4 Swap:     25151484     224188   24927296

free的輸出一共有四行,第四行爲交換區的信息,分別是交換的總量(total),使用量(used)和有多少空閒的交換區(free),這個比較清楚,不說太多。

free輸出地第二行和第三行是比較讓人迷惑的。這兩行都是說明內存使用狀況的。第一列是總量(total),第二列是使用量(used),第三列是可用量(free)。

  第一行的輸出時從操做系統(OS)來看的。也就是說,從OS的角度來看,計算機上一共有:

24677460KB(缺省時free的單位爲KB)物理內存,即FO[2][1]; 在這些物理內存中有23276064KB(即FO[2][2])被使用了; 還用1401396KB(即FO[2][3])是可用的;

這裏獲得第一個等式:

FO[2][1] = FO[2][2] + FO[2][3]

FO[2][4]表示被幾個進程共享的內存的,如今已經deprecated,其值老是0(固然在一些系統上也可能不是0,主要取決於free命令是怎麼實現的)。

FO[2][5]表示被OS buffer住的內存。FO[2][6]表示被OS cache的內存。在有些時候buffer和cache這兩個詞常常混用。不過在一些比較低層的軟件裏是要區分這兩個詞的,看老外的洋文:

A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use. 

也就是說buffer是用於存放要輸出到disk(塊設備)的數據的,而cache是存放從disk上讀出的數據。這兩者是爲了提升IO性能的,並由OS管理。

Linux和其餘成熟的操做系統(例如windows),爲了提升IO read的性能,老是要多cache一些數據,這也就是爲何FO[2][6](cached memory)比較大,而FO[2][3]比較小的緣由。咱們能夠作一個簡單的測試:

釋放掉被系統cache佔用的數據:

echo 3>/proc/sys/vm/drop_caches 
  1. 讀一個大文件,並記錄時間;
  2. 關閉該文件;
  3. 重讀這個大文件,並記錄時間;

第二次讀應該比第一次快不少。原來我作過一個BerkeleyDB的讀操做,大概要讀5G的文件,幾千萬條記錄。在個人環境上,第二次讀比第一次大概能夠快9倍左右。

free輸出的第二行是從一個應用程序的角度看系統內存的使用狀況。

  • 對於FO[3][2],即-buffers/cache,表示一個應用程序認爲系統被用掉多少內存;
  • 對於FO[3][3],即+buffers/cache,表示一個應用程序認爲系統還有多少內存;

由於被系統cache和buffer佔用的內存能夠被快速回收,因此一般FO[3][3]比FO[2][3]會大不少。

這裏還用兩個等式:

FO[3][2] = FO[2][2] - FO[2][5] - FO[2][6] FO[3][3] = FO[2][3] + FO[2][5] + FO[2][6] 

這兩者都不難理解。

free命令由procps.*.rpm提供(在Redhat系列的OS上)。free命令的全部輸出值都是從/proc/meminfo中讀出的。

在系統上可能有meminfo(2)這個函數,它就是爲了解析/proc/meminfo的。procps這個包本身實現了meminfo()這個函數。能夠下載一個procps的tar包看看具體實現,如今最新版式3.2.8。

文章出處:

http://www.cnblogs.com/coldplayerest/archive/2010/02/20/1669949.html

10. vmstat 監視內存使用狀況

vmstat是Virtual Meomory Statistics(虛擬內存統計)的縮寫,可實時動態監視操做系統的虛擬內存、進程、CPU活動。

10.1. vmstat的語法

  vmstat [-V] [-n] [delay [count]]

  • -V表示打印出版本信息;
  • -n表示在週期性循環輸出時,輸出的頭部信息僅顯示一次;
  • delay是兩次輸出之間的延遲時間;
  • count是指按照這個時間間隔統計的次數。
/root$vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
6  0      0 27900472 204216 28188356    0    0     0     9    1    2 11 14 75  0  0
9  0      0 27900380 204228 28188360    0    0     0    13 33312 126221 22 20 58  0  0
2  0      0 27900340 204240 28188364    0    0     0    10 32755 125566 22 20 58  0  0

10.2. 字段說明

Procs(進程):
  • r: 運行隊列中進程數量
  • b: 等待IO的進程數量
Memory(內存):
  • swpd: 使用虛擬內存大小
  • free: 可用內存大小
  • buff: 用做緩衝的內存大小
  • cache: 用做緩存的內存大小
Swap:
  • si: 每秒從交換區寫到內存的大小
  • so: 每秒寫入交換區的內存大小
IO:(如今的Linux版本塊的大小爲1024bytes)
  • bi: 每秒讀取的塊數
  • bo: 每秒寫入的塊數
system:
  • in: 每秒中斷數,包括時鐘中斷
  • cs: 每秒上下文切換數
CPU(以百分比表示)
  • us: 用戶進程執行時間(user time)
  • sy: 系統進程執行時間(system time)
  • id: 空閒時間(包括IO等待時間)
  • wa: 等待IO時間

11. iostat 監視I/O子系統

iostat是I/O statistics(輸入/輸出統計)的縮寫,用來動態監視系統的磁盤操做活動。

11.1. 命令格式

iostat[參數][時間][次數]

11.2. 命令功能

經過iostat方便查看CPU、網卡、tty設備、磁盤、CD-ROM 等等設備的活動狀況, 負載信息。

11.3. 命令參數

  • -C 顯示CPU使用狀況
  • -d 顯示磁盤使用狀況
  • -k 以 KB 爲單位顯示
  • -m 以 M 爲單位顯示
  • -N 顯示磁盤陣列(LVM) 信息
  • -n 顯示NFS 使用狀況
  • -p[磁盤] 顯示磁盤和分區的狀況
  • -t 顯示終端和CPU的信息
  • -x 顯示詳細信息
  • -V 顯示版本信息

11.4. 工具實例

實例1:顯示全部設備負載狀況

/root$iostat
Linux 2.6.32-279.el6.x86_64 (colin)   07/16/2014      _x86_64_        (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
10.81    0.00   14.11    0.18    0.00   74.90

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               1.95         1.48        70.88    9145160  437100644
dm-0              3.08         0.55        24.34    3392770  150087080
dm-1              5.83         0.93        46.49    5714522  286724168
dm-2              0.01         0.00         0.05      23930     289288
cpu屬性值說明:
  • %user:CPU處在用戶模式下的時間百分比。
  • %nice:CPU處在帶NICE值的用戶模式下的時間百分比。
  • %system:CPU處在系統模式下的時間百分比。
  • %iowait:CPU等待輸入輸出完成時間的百分比。
  • %steal:管理程序維護另外一個虛擬處理器時,虛擬CPU的無心識等待時間百分比。
  • %idle:CPU空閒時間百分比。

注:若是%iowait的值太高,表示硬盤存在I/O瓶頸,%idle值高,表示CPU較空閒,若是%idle值高但系統響應慢時,有多是CPU等待分配內存,此時應加大內存容量。%idle值若是持續低於10,那麼系統的CPU處理能力相對較低,代表系統中最須要解決的資源是CPU。

disk屬性值說明:
  • rrqm/s: 每秒進行 merge 的讀操做數目。即 rmerge/s
  • wrqm/s: 每秒進行 merge 的寫操做數目。即 wmerge/s
  • r/s: 每秒完成的讀 I/O 設備次數。即 rio/s
  • w/s: 每秒完成的寫 I/O 設備次數。即 wio/s
  • rsec/s: 每秒讀扇區數。即 rsect/s
  • wsec/s: 每秒寫扇區數。即 wsect/s
  • rkB/s: 每秒讀K字節數。是 rsect/s 的一半,由於每扇區大小爲512字節。
  • wkB/s: 每秒寫K字節數。是 wsect/s 的一半。
  • avgrq-sz: 平均每次設備I/O操做的數據大小 (扇區)。
  • avgqu-sz: 平均I/O隊列長度。
  • await: 平均每次設備I/O操做的等待時間 (毫秒)。
  • svctm: 平均每次設備I/O操做的服務時間 (毫秒)。
  • %util: 一秒中有百分之多少的時間用於 I/O 操做,即被io消耗的cpu百分比

備註:若是 %util 接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁盤可能存在瓶頸。若是 svctm 比較接近 await,說明 I/O 幾乎沒有等待時間;若是 await 遠大於 svctm,說明I/O 隊列太長,io響應太慢,則須要進行必要優化。若是avgqu-sz比較大,也表示有當量io在等待。

實例2:定時顯示全部信息

/root$iostat 2 3
Linux 2.6.32-279.el6.x86_64 (colin)   07/16/2014      _x86_64_        (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
10.81    0.00   14.11    0.18    0.00   74.90

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               1.95         1.48        70.88    9145160  437106156
dm-0              3.08         0.55        24.34    3392770  150088376
dm-1              5.83         0.93        46.49    5714522  286728384
dm-2              0.01         0.00         0.05      23930     289288

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
22.62    0.00   19.67    0.26    0.00   57.46

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               2.50         0.00        28.00          0         56
dm-0              0.00         0.00         0.00          0          0
dm-1              3.50         0.00        28.00          0         56
dm-2              0.00         0.00         0.00          0          0

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
22.69    0.00   19.62    0.00    0.00   57.69

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               0.00         0.00         0.00          0          0
dm-0              0.00         0.00         0.00          0          0
dm-1              0.00         0.00         0.00          0          0
dm-2              0.00         0.00         0.00          0          0

說明:每隔 2秒刷新顯示,且顯示3次

實例3:查看TPS和吞吐量

/root$iostat -d -k 1 1
Linux 2.6.32-279.el6.x86_64 (colin)   07/16/2014      _x86_64_        (4 CPU)

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               1.95         0.74        35.44    4572712  218559410
dm-0              3.08         0.28        12.17    1696513   75045968
dm-1              5.83         0.46        23.25    2857265  143368744
dm-2              0.01         0.00         0.02      11965     144644
  • tps:該設備每秒的傳輸次數(Indicate the number of transfers per second that were issued to the device.)。「一次傳輸」意思是「一次I/O請求」。多個邏輯請求可能會被合併爲「一次I/O請求」。「一次傳輸」請求的大小是未知的。
  • kB_read/s:每秒從設備(drive expressed)讀取的數據量;
  • kB_wrtn/s:每秒向設備(drive expressed)寫入的數據量;
  • kB_read:讀取的總數據量;kB_wrtn:寫入的總數量數據量;

這些單位都爲Kilobytes。

上面的例子中,咱們能夠看到磁盤sda以及它的各個分區的統計數據,當時統計的磁盤總TPS是1.95,下面是各個分區的TPS。(由於是瞬間值,因此總TPS並不嚴格等於各個分區TPS的總和)

實例4:查看設備使用率(%util)和響應時間(await)

/root$iostat -d -x -k 1 1
Linux 2.6.32-279.el6.x86_64 (colin)   07/16/2014      _x86_64_        (4 CPU)

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.02     7.25    0.04    1.90     0.74    35.47    37.15     0.04   19.13   5.58   1.09
dm-0              0.00     0.00    0.04    3.05     0.28    12.18     8.07     0.65  209.01   1.11   0.34
dm-1              0.00     0.00    0.02    5.82     0.46    23.26     8.13     0.43   74.33   1.30   0.76
dm-2              0.00     0.00    0.00    0.01     0.00     0.02     8.00     0.00    5.41   3.28   0.00
  • rrqm/s: 每秒進行 merge 的讀操做數目.即 delta(rmerge)/s
  • wrqm/s: 每秒進行 merge 的寫操做數目.即 delta(wmerge)/s
  • r/s: 每秒完成的讀 I/O 設備次數.即 delta(rio)/s
  • w/s: 每秒完成的寫 I/O 設備次數.即 delta(wio)/s
  • rsec/s: 每秒讀扇區數.即 delta(rsect)/s
  • wsec/s: 每秒寫扇區數.即 delta(wsect)/s
  • rkB/s: 每秒讀K字節數.是 rsect/s 的一半,由於每扇區大小爲512字節.(須要計算)
  • wkB/s: 每秒寫K字節數.是 wsect/s 的一半.(須要計算)
  • avgrq-sz:平均每次設備I/O操做的數據大小 (扇區).delta(rsect+wsect)/delta(rio+wio)
  • avgqu-sz:平均I/O隊列長度.即 delta(aveq)/s/1000 (由於aveq的單位爲毫秒).
  • await: 平均每次設備I/O操做的等待時間 (毫秒).即 delta(ruse+wuse)/delta(rio+wio)
  • svctm: 平均每次設備I/O操做的服務時間 (毫秒).即 delta(use)/delta(rio+wio)
  • %util: 一秒中有百分之多少的時間用於 I/O 操做,或者說一秒中有多少時間 I/O 隊列是非空的,即 delta(use)/s/1000 (由於use的單位爲毫秒)

若是 %util 接近 100%,說明產生的I/O請求太多,I/O系統已經滿負荷,該磁盤可能存在瓶頸。 idle小於70% IO壓力就較大了,通常讀取速度有較多的wait。 同時能夠結合vmstat 查看查看b參數(等待資源的進程數)和wa參數(IO等待所佔用的CPU時間的百分比,高過30%時IO壓力高)。

另外 await 的參數也要多和 svctm 來參考。差的太高就必定有 IO 的問題。

avgqu-sz 也是個作 IO 調優時須要注意的地方,這個就是直接每次操做的數據的大小,若是次數多,但數據拿的小的話,其實 IO 也會很小。若是數據拿的大,才IO 的數據會高。也能夠經過 avgqu-sz × ( r/s or w/s ) = rsec/s or wsec/s。也就是講,讀定速度是這個來決定的。

svctm 通常要小於 await (由於同時等待的請求的等待時間被重複計算了),svctm 的大小通常和磁盤性能有關,CPU/內存的負荷也會對其有影響,請求過多也會間接致使 svctm 的增長。await 的大小通常取決於服務時間(svctm) 以及 I/O 隊列的長度和 I/O 請求的發出模式。若是 svctm 比較接近 await,說明 I/O 幾乎沒有等待時間;若是 await 遠大於 svctm,說明 I/O 隊列太長,應用獲得的響應時間變慢,若是響應時間超過了用戶能夠允許的範圍,這時能夠考慮更換更快的磁盤,調整內核 elevator 算法,優化應用,或者升級 CPU。

隊列長度(avgqu-sz)也可做爲衡量系統 I/O 負荷的指標,但因爲 avgqu-sz 是按照單位時間的平均值,因此不能反映瞬間的 I/O 洪水。

形象的比喻:
  • r/s+w/s 相似於交款人的總數
  • 平均隊列長度(avgqu-sz)相似於單位時間裏平均排隊人的個數
  • 平均服務時間(svctm)相似於收銀員的收款速度
  • 平均等待時間(await)相似於平均每人的等待時間
  • 平均I/O數據(avgrq-sz)相似於平均每人所買的東西多少
  • I/O 操做率 (%util)相似於收款臺前有人排隊的時間比例

設備IO操做:總IO(io)/s = r/s(讀) +w/s(寫)

平均等待時間=單個I/O服務器時間*(1+2+...+請求總數-1)/請求總數

每秒發出的I/0請求不少,可是平均隊列就4,表示這些請求比較均勻,大部分處理仍是比較及時。

12. sar 找出系統瓶頸的利器

sar是System Activity Reporter(系統活動狀況報告)的縮寫。sar工具將對系統當前的狀態進行取樣,而後經過計算數據和比例來表達系統的當前運行狀態。它的特色是能夠連續對系統取樣,得到大量的取樣數據;取樣數據和分析的結果均可以存入文件,所需的負載很小。sar是目前Linux上最爲全面的系統性能分析工具之一,能夠從14個大方面對系統的活動進行報告,包括文件的讀寫狀況、系統調用的使用狀況、串口、CPU效率、內存使用情況、進程活動及IPC有關的活動等,使用也是較爲複雜。

sar是查看操做系統報告指標的各類工具中,最爲廣泛和方便的;它有兩種用法;

  1. 追溯過去的統計數據(默認)
  2. 週期性的查看當前數據

12.1. 追溯過去的統計數據

默認狀況下,sar從最近的0點0分開始顯示數據;若是想繼續查看一天前的報告;能夠查看保存在/var/log/sysstat/下的sa日誌; 使用sar工具查看:

$sar -f /var/log/sysstat/sa28 \| head sar -r -f
/var/log/sysstat/sa28
../_images/sar1.png

12.2. 查看CPU使用率

sar -u : 默認狀況下顯示的cpu使用率等信息就是sar -u;

../_images/sar2.png

能夠看到這臺機器使用了虛擬化技術,有相應的時間消耗; 各列的指標分別是:

  • %user 用戶模式下消耗的CPU時間的比例;
  • %nice 經過nice改變了進程調度優先級的進程,在用戶模式下消耗的CPU時間的比例
  • %system 系統模式下消耗的CPU時間的比例;
  • %iowait CPU等待磁盤I/O致使空閒狀態消耗的時間比例;
  • %steal 利用Xen等操做系統虛擬化技術,等待其它虛擬CPU計算佔用的時間比例;
  • %idle CPU空閒時間比例;

12.3. 查看平均負載

sar -q: 查看平均負載

指定-q後,就能查看運行隊列中的進程數、系統上的進程大小、平均負載等;與其它命令相比,它能查看各項指標隨時間變化的狀況;

  • runq-sz:運行隊列的長度(等待運行的進程數)
  • plist-sz:進程列表中進程(processes)和線程(threads)的數量
  • ldavg-1:最後1分鐘的系統平均負載 ldavg-5:過去5分鐘的系統平均負載
  • ldavg-15:過去15分鐘的系統平均負載
../_images/sar3.png

12.4. 查看內存使用情況

sar -r: 指定-r以後,可查看物理內存使用情況;

../_images/sar4.png
  • kbmemfree:這個值和free命令中的free值基本一致,因此它不包括buffer和cache的空間.
  • kbmemused:這個值和free命令中的used值基本一致,因此它包括buffer和cache的空間.
  • %memused:物理內存使用率,這個值是kbmemused和內存總量(不包括swap)的一個百分比.
  • kbbuffers和kbcached:這兩個值就是free命令中的buffer和cache.
  • kbcommit:保證當前系統所須要的內存,即爲了確保不溢出而須要的內存(RAM+swap).
  • %commit:這個值是kbcommit與內存總量(包括swap)的一個百分比.

12.5. 查看頁面交換髮生情況

sar -W:查看頁面交換髮生情況

頁面發生交換時,服務器的吞吐量會大幅降低;服務器情況不良時,若是懷疑由於內存不足而致使了頁面交換的發生,可使用這個命令來確認是否發生了大量的交換;

../_images/sar5.png
  • pswpin/s:每秒系統換入的交換頁面(swap page)數量
  • pswpout/s:每秒系統換出的交換頁面(swap page)數量

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

  • 懷疑CPU存在瓶頸,可用 sar -u 和 sar -q 等來查看
  • 懷疑內存存在瓶頸,可用sar -B、sar -r 和 sar -W 等來查看
  • 懷疑I/O存在瓶頸,可用 sar -b、sar -u 和 sar -d 等來查看

12.6. 安裝

  1. 有的linux系統下,默承認能沒有安裝這個包,使用apt-get install sysstat 來安裝;
  2. 安裝完畢,將性能收集工具的開關打開: vi /etc/default/sysstat
設置 ENABLED=」true」
  1. 啓動這個工具來收集系統性能數據: /etc/init.d/sysstat start

12.7. sar參數說明

  • -A 彙總全部的報告
  • -a 報告文件讀寫使用狀況
  • -B 報告附加的緩存的使用狀況
  • -b 報告緩存的使用狀況
  • -c 報告系統調用的使用狀況
  • -d 報告磁盤的使用狀況
  • -g 報告串口的使用狀況
  • -h 報告關於buffer使用的統計數據
  • -m 報告IPC消息隊列和信號量的使用狀況
  • -n 報告命名cache的使用狀況
  • -p 報告調頁活動的使用狀況
  • -q 報告運行隊列和交換隊列的平均長度
  • -R 報告進程的活動狀況
  • -r 報告沒有使用的內存頁面和硬盤塊
  • -u 報告CPU的利用率
  • -v 報告進程、i節點、文件和鎖表狀態
  • -w 報告系統交換活動情況
  • -y 報告TTY設備活動情況

13. readelf elf文件格式分析

這個工具和objdump命令提供的功能相似,可是它顯示的信息更爲具體,而且它不依賴BFD庫(BFD庫是一個GNU項目,它的目標就是但願經過一種統一的接口來處理不一樣的目標文件);

ELF文件類型
ELF(Executable and Linking Format)是一種對象文件的格式,用於定義不一樣類型的對象文件(Object files)中都放了什麼東西、以及都以什麼樣的格式去放這些東西。它自最先在 System V 系統上出現後,被 xNIX 世界所普遍接受,做爲缺省的二進制文件格式來使用。能夠說,ELF是構成衆多xNIX系統的基礎之一。

ELF文件有三種類型:

  1. 可重定位的對象文件(Relocatable file)
    由彙編器彙編生成的 .o 文件
  2. 可執行的對象文件(Executable file)
    可執行應用程序
  3. 可被共享的對象文件(Shared object file)
    動態庫文件,也即 .so 文件
  • .text section 裏裝載了可執行代碼;
  • .data section 裏面裝載了被初始化的數據;
  • .bss section 裏面裝載了未被初始化的數據;
  • 以 .rec 打頭的 sections 裏面裝載了重定位條目;
  • .symtab 或者 .dynsym section 裏面裝載了符號信息;
  • .strtab 或者 .dynstr section 裏面裝載了字符串信息;

13.1. 參數說明

  • -a –all 所有 Equivalent to: -h -l -S -s -r -d -V -A -I

  • -h –file-header 文件頭 Display the ELF file header

  • -l –program-headers 程序 Display the program headers

  • –segments An alias for –program-headers

  • -S –section-headers 段頭 Display the sections’ header

  • --sections      An alias for –section-headers
  • -e –headers 所有頭 Equivalent to: -h -l -S

  • -s –syms 符號表 Display the symbol table

  • --symbols     An alias for –syms
  • -n –notes 內核註釋 Display the core notes (if present)

  • -r –relocs 重定位 Display the relocations (if present)

  • -u –unwind Display the unwind info (if present)

  • -d –dynamic 動態段 Display the dynamic segment (if present)

  • -V –version-info 版本 Display the version sections (if present)

  • -A –arch-specific CPU構架 Display architecture specific information (if any).

  • -D –use-dynamic 動態段 Use the dynamic section info when displaying symbols

  • -x –hex-dump=<number> 顯示 段內內容Dump the contents of section <number>

  • -w[liaprmfFso] or

  • -I –histogram Display histogram of bucket list lengths

  • -W –wide 寬行輸出 Allow output width to exceed 80 characters

  • -H –help Display this information

  • -v –version Display the version number of readelf

13.2. 示例

想知道一個應用程序的可運行的架構平臺:

$readelf -h main| grep Machine

-h選項將顯示文件頭的概要信息,從裏面能夠看到,有不少有用的信息:

$readelf -h main
ELF Header:
Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class:                             ELF64
Data:                              2 s complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              EXEC (Executable file)
Machine:                           Advanced Micro Devices X86-64
Version:                           0x1
Entry point address:               0x400790
Start of program headers:          64 (bytes into file)
Start of section headers:          5224 (bytes into file)
Flags:                             0x0
Size of this header:               64 (bytes)
Size of program headers:           56 (bytes)
Number of program headers:         8
Size of section headers:           64 (bytes)
Number of section headers:         29
Section header string table index: 26

一個編譯好的應用程序,想知道其編譯時是否使用了-g選項(加入調試信息):

$readelf -S main| grep debug

用-S選項是顯示全部段信息;若是編譯時使用了-g選項,則會有debug段;

查看.o文件是否編入了調試信息(編譯的時候是否加了-g):

$readelf -S Shpos.o | grep debug

13.3. 完整輸出

readelf輸出的完整內容:

$readelf -all a.out
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x8048330
  Start of program headers:          52 (bytes into file)
  Start of section headers:          4412 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         9
  Size of section headers:           40 (bytes)
  Number of section headers:         30
  Section header string table index: 27

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        08048154 000154 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048168 000168 000020 00   A  0   0  4
  [ 3] .note.gnu.build-i NOTE            08048188 000188 000024 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        080481ac 0001ac 000020 04   A  5   0  4
  [ 5] .dynsym           DYNSYM          080481cc 0001cc 000050 10   A  6   1  4
  [ 6] .dynstr           STRTAB          0804821c 00021c 00004c 00   A  0   0  1
  [ 7] .gnu.version      VERSYM          08048268 000268 00000a 02   A  5   0  2
  [ 8] .gnu.version_r    VERNEED         08048274 000274 000020 00   A  6   1  4
  [ 9] .rel.dyn          REL             08048294 000294 000008 08   A  5   0  4
  [10] .rel.plt          REL             0804829c 00029c 000018 08   A  5  12  4
  [11] .init             PROGBITS        080482b4 0002b4 00002e 00  AX  0   0  4
  [12] .plt              PROGBITS        080482f0 0002f0 000040 04  AX  0   0 16
  [13] .text             PROGBITS        08048330 000330 00018c 00  AX  0   0 16
  [14] .fini             PROGBITS        080484bc 0004bc 00001a 00  AX  0   0  4
  [15] .rodata           PROGBITS        080484d8 0004d8 000011 00   A  0   0  4
  [16] .eh_frame_hdr     PROGBITS        080484ec 0004ec 000034 00   A  0   0  4
  [17] .eh_frame         PROGBITS        08048520 000520 0000c4 00   A  0   0  4
  [18] .ctors            PROGBITS        08049f14 000f14 000008 00  WA  0   0  4
  [19] .dtors            PROGBITS        08049f1c 000f1c 000008 00  WA  0   0  4
  [20] .jcr              PROGBITS        08049f24 000f24 000004 00  WA  0   0  4
  [21] .dynamic          DYNAMIC         08049f28 000f28 0000c8 08  WA  6   0  4
  [22] .got              PROGBITS        08049ff0 000ff0 000004 04  WA  0   0  4
  [23] .got.plt          PROGBITS        08049ff4 000ff4 000018 04  WA  0   0  4
  [24] .data             PROGBITS        0804a00c 00100c 000008 00  WA  0   0  4
  [25] .bss              NOBITS          0804a014 001014 000008 00  WA  0   0  4
  [26] .comment          PROGBITS        00000000 001014 00002a 01  MS  0   0  1
  [27] .shstrtab         STRTAB          00000000 00103e 0000fc 00      0   0  1
  [28] .symtab           SYMTAB          00000000 0015ec 000410 10     29  45  4
  [29] .strtab           STRTAB          00000000 0019fc 0001f9 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4
  INTERP         0x000154 0x08048154 0x08048154 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x005e4 0x005e4 R E 0x1000
  LOAD           0x000f14 0x08049f14 0x08049f14 0x00100 0x00108 RW  0x1000
  DYNAMIC        0x000f28 0x08049f28 0x08049f28 0x000c8 0x000c8 RW  0x4
  NOTE           0x000168 0x08048168 0x08048168 0x00044 0x00044 R   0x4
  GNU_EH_FRAME   0x0004ec 0x080484ec 0x080484ec 0x00034 0x00034 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4
  GNU_RELRO      0x000f14 0x08049f14 0x08049f14 0x000ec 0x000ec R   0x1

 Section to Segment mapping:
  Segment Sections...
   00
   01     .interp
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
   03     .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
   04     .dynamic
   05     .note.ABI-tag .note.gnu.build-id
   06     .eh_frame_hdr
   07
   08     .ctors .dtors .jcr .dynamic .got

Dynamic section at offset 0xf28 contains 20 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x0000000c (INIT)                       0x80482b4
 0x0000000d (FINI)                       0x80484bc
 0x6ffffef5 (GNU_HASH)                   0x80481ac
 0x00000005 (STRTAB)                     0x804821c
 0x00000006 (SYMTAB)                     0x80481cc
 0x0000000a (STRSZ)                      76 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000015 (DEBUG)                      0x0
 0x00000003 (PLTGOT)                     0x8049ff4
 0x00000002 (PLTRELSZ)                   24 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x804829c
 0x00000011 (REL)                        0x8048294
 0x00000012 (RELSZ)                      8 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffe (VERNEED)                    0x8048274
 0x6fffffff (VERNEEDNUM)                 1
 0x6ffffff0 (VERSYM)                     0x8048268
 0x00000000 (NULL)                       0x0

Relocation section '.rel.dyn' at offset 0x294 contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
08049ff0  00000206 R_386_GLOB_DAT    00000000   __gmon_start__

Relocation section '.rel.plt' at offset 0x29c contains 3 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0804a000  00000107 R_386_JUMP_SLOT   00000000   printf
0804a004  00000207 R_386_JUMP_SLOT   00000000   __gmon_start__
0804a008  00000307 R_386_JUMP_SLOT   00000000   __libc_start_main

There are no unwind sections in this file.

Symbol table '.dynsym' contains 5 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FUNC    GLOBAL DEFAULT  UND printf@GLIBC_2.0 (2)
     2: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.0 (2)
     4: 080484dc     4 OBJECT  GLOBAL DEFAULT   15 _IO_stdin_used

Symbol table '.symtab' contains 65 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 08048154     0 SECTION LOCAL  DEFAULT    1
     2: 08048168     0 SECTION LOCAL  DEFAULT    2
     3: 08048188     0 SECTION LOCAL  DEFAULT    3
     4: 080481ac     0 SECTION LOCAL  DEFAULT    4
     5: 080481cc     0 SECTION LOCAL  DEFAULT    5
     6: 0804821c     0 SECTION LOCAL  DEFAULT    6
     7: 08048268     0 SECTION LOCAL  DEFAULT    7
     8: 08048274     0 SECTION LOCAL  DEFAULT    8
     9: 08048294     0 SECTION LOCAL  DEFAULT    9
    10: 0804829c     0 SECTION LOCAL  DEFAULT   10
    11: 080482b4     0 SECTION LOCAL  DEFAULT   11
    12: 080482f0     0 SECTION LOCAL  DEFAULT   12
    13: 08048330     0 SECTION LOCAL  DEFAULT   13
    14: 080484bc     0 SECTION LOCAL  DEFAULT   14
    15: 080484d8     0 SECTION LOCAL  DEFAULT   15
    16: 080484ec     0 SECTION LOCAL  DEFAULT   16
    17: 08048520     0 SECTION LOCAL  DEFAULT   17
    18: 08049f14     0 SECTION LOCAL  DEFAULT   18
    19: 08049f1c     0 SECTION LOCAL  DEFAULT   19
    20: 08049f24     0 SECTION LOCAL  DEFAULT   20
    21: 08049f28     0 SECTION LOCAL  DEFAULT   21
    22: 08049ff0     0 SECTION LOCAL  DEFAULT   22
    23: 08049ff4     0 SECTION LOCAL  DEFAULT   23
    24: 0804a00c     0 SECTION LOCAL  DEFAULT   24
    25: 0804a014     0 SECTION LOCAL  DEFAULT   25
    26: 00000000     0 SECTION LOCAL  DEFAULT   26
    27: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    28: 08049f14     0 OBJECT  LOCAL  DEFAULT   18 __CTOR_LIST__
    29: 08049f1c     0 OBJECT  LOCAL  DEFAULT   19 __DTOR_LIST__
    30: 08049f24     0 OBJECT  LOCAL  DEFAULT   20 __JCR_LIST__
    31: 08048360     0 FUNC    LOCAL  DEFAULT   13 __do_global_dtors_aux
    32: 0804a014     1 OBJECT  LOCAL  DEFAULT   25 completed.6086
    33: 0804a018     4 OBJECT  LOCAL  DEFAULT   25 dtor_idx.6088
    34: 080483c0     0 FUNC    LOCAL  DEFAULT   13 frame_dummy
    35: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    36: 08049f18     0 OBJECT  LOCAL  DEFAULT   18 __CTOR_END__
    37: 080485e0     0 OBJECT  LOCAL  DEFAULT   17 __FRAME_END__
    38: 08049f24     0 OBJECT  LOCAL  DEFAULT   20 __JCR_END__
    39: 08048490     0 FUNC    LOCAL  DEFAULT   13 __do_global_ctors_aux
    40: 00000000     0 FILE    LOCAL  DEFAULT  ABS a.c
    41: 08049f14     0 NOTYPE  LOCAL  DEFAULT   18 __init_array_end
    42: 08049f28     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC
    43: 08049f14     0 NOTYPE  LOCAL  DEFAULT   18 __init_array_start
    44: 08049ff4     0 OBJECT  LOCAL  DEFAULT   23 _GLOBAL_OFFSET_TABLE_
    45: 08048480     2 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
    46: 08048482     0 FUNC    GLOBAL HIDDEN    13 __i686.get_pc_thunk.bx
    47: 0804a00c     0 NOTYPE  WEAK   DEFAULT   24 data_start
    48: 00000000     0 FUNC    GLOBAL DEFAULT  UND printf@@GLIBC_2.0
    49: 0804a014     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    50: 080484bc     0 FUNC    GLOBAL DEFAULT   14 _fini
    51: 08049f20     0 OBJECT  GLOBAL HIDDEN    19 __DTOR_END__
    52: 0804a00c     0 NOTYPE  GLOBAL DEFAULT   24 __data_start
    53: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    54: 0804a010     0 OBJECT  GLOBAL HIDDEN    24 __dso_handle
    55: 080484dc     4 OBJECT  GLOBAL DEFAULT   15 _IO_stdin_used
    56: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    57: 08048410    97 FUNC    GLOBAL DEFAULT   13 __libc_csu_init
    58: 0804a01c     0 NOTYPE  GLOBAL DEFAULT  ABS _end
    59: 08048330     0 FUNC    GLOBAL DEFAULT   13 _start
    60: 080484d8     4 OBJECT  GLOBAL DEFAULT   15 _fp_hw
    61: 0804a014     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    62: 080483e4    40 FUNC    GLOBAL DEFAULT   13 main
    63: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    64: 080482b4     0 FUNC    GLOBAL DEFAULT   11 _init

Histogram for `.gnu.hash' bucket list length (total of 2 buckets):
 Length  Number     % of total  Coverage
      0  1          ( 50.0%)
      1  1          ( 50.0%)    100.0%

Version symbols section '.gnu.version' contains 5 entries:
 Addr: 0000000008048268  Offset: 0x000268  Link: 5 (.dynsym)
  000:   0 (*local*)       2 (GLIBC_2.0)     0 (*local*)       2 (GLIBC_2.0)
  004:   1 (*global*)

Version needs section '.gnu.version_r' contains 1 entries:
 Addr: 0x0000000008048274  Offset: 0x000274  Link: 6 (.dynstr)
  000000: Version: 1  File: libc.so.6  Cnt: 1
  0x0010:   Name: GLIBC_2.0  Flags: none  Version: 2

Notes at offset 0x00000168 with length 0x00000020:
  Owner                 Data size   Description
  GNU                  0x00000010   NT_GNU_ABI_TAG (ABI version tag)
    OS: Linux, ABI: 2.6.15

Notes at offset 0x00000188 with length 0x00000024:
  Owner                 Data size   Description
  GNU                  0x00000014   NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 17fb9651029b6a8543bfafec9eea23bd16454e65

關於ELF文件格式的參考:http://www.cnblogs.com/xmphoenix/archive/2011/10/23/2221879.html

14. objdump 二進制文件分析

objdump工具用來顯示二進制文件的信息,就是以一種可閱讀的格式讓你更多地瞭解二進制文件可能帶有的附加信息。

14.1. 經常使用參數說明

  • -f 顯示文件頭信息
  • -D 反彙編全部section (-d反彙編特定section)
  • -h 顯示目標文件各個section的頭部摘要信息
  • -x 顯示全部可用的頭信息,包括符號表、重定位入口。-x 等價於 -a -f -h -r -t 同時指定。
  • -i 顯示對於 -b 或者 -m 選項可用的架構和目標格式列表。
  • -r 顯示文件的重定位入口。若是和-d或者-D一塊兒使用,重定位部分以反彙編後的格式顯示出來。
  • -R 顯示文件的動態重定位入口,僅僅對於動態目標文件有意義,好比某些共享庫。
  • -S 儘量反彙編出源代碼,尤爲當編譯的時候指定了-g這種調試參數時,效果比較明顯。隱含了-d參數。
  • -t 顯示文件的符號表入口。相似於nm -s提供的信息

14.2. 示例

查看本機目標結構(使用大端仍是小端存儲):

$objdump -i

反彙編程序:

$objdump -d main.o

顯示符號表入口:

$objdump  -t main.o

但願顯示可用的簡潔幫助信息,直接輸入objdump便可;(objdump -H)

15. nm 目標文件格式分析

nm 命令顯示關於指定 File 中符號的信息,文件能夠是對象文件、可執行文件或對象文件庫。若是文件沒有包含符號信息,nm 命令報告該狀況,但不把它解釋爲出錯條件。 nm 命令缺省狀況下報告十進制符號表示法下的數字值。

$nm myProgrammer
08049f28 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
080484dc R _IO_stdin_used
         w _Jv_RegisterClasses
08049f18 d __CTOR_END__
08049f14 d __CTOR_LIST__
08049f20 D __DTOR_END__
08049f1c d __DTOR_LIST__
080485e0 r __FRAME_END__
08049f24 d __JCR_END__
08049f24 d __JCR_LIST__
0804a014 A __bss_start
0804a00c D __data_start
08048490 t __do_global_ctors_aux
08048360 t __do_global_dtors_aux
0804a010 D __dso_handle
         w __gmon_start__
08048482 T __i686.get_pc_thunk.bx
08049f14 d __init_array_end
08049f14 d __init_array_start
08048480 T __libc_csu_fini
08048410 T __libc_csu_init
         U __libc_start_main@@GLIBC_2.0
0804a014 A _edata
0804a01c A _end
080484bc T _fini
080484d8 R _fp_hw
080482b4 T _init
08048330 T _start
0804a014 b completed.6086
0804a00c W data_start
0804a018 b dtor_idx.6088
080483c0 t frame_dummy
080483e4 T main
         U printf@@GLIBC_2.0

這些包含可執行代碼的段稱爲正文段。一樣地,數據段包含了不可執行的信息或數據。另外一種類型的段,稱爲 BSS 段,它包含以符號數據開頭的塊。對於 nm 命令列出的每一個符號,它們的值使用十六進制來表示(缺省行爲),而且在該符號前面加上了一個表示符號類型的編碼字符。

能夠將目標文件中所包含的不一樣的部分劃分爲段。段能夠包含可執行代碼、符號名稱、初始數據值和許多其餘類型的數據。有關這些類型的數據的詳細信息,能夠閱讀 UNIX 中 nm 的 man 頁面,其中按照該命令輸出中的字符編碼分別對每種類型進行了描述。

15.1. 選項說明

  • -a或–debug-syms:顯示全部的符號,包括debugger-only symbols。
  • -B:等同於–format=bsd,用來兼容MIPS的nm。
  • -C或–demangle:將低級符號名解析(demangle)成用戶級名字。這樣可使得C++函數名具備可讀性。
  • –no-demangle:默認的選項,不須要將低級符號名解析成用戶級名。
  • -D或–dynamic:顯示動態符號。該任選項僅對於動態目標(例如特定類型的共享庫)有意義。
  • -f format:使用format格式輸出。format能夠選取bsd、sysv或posix,該選項在GNU的nm中有用。默認爲bsd。
  • -g或–extern-only:僅顯示外部符號。
  • -n、-v或–numeric-sort:按符號對應地址的順序排序,而非按符號名的字符順序。
  • -p或–no-sort:按目標文件中遇到的符號順序顯示,不排序。
  • -P或–portability:使用POSIX.2標準輸出格式代替默認的輸出格式。等同於使用任選項-f posix。
  • -s或–print-armap:當列出庫中成員的符號時,包含索引。索引的內容包含:哪些模塊包含哪些名字的映射。
  • -r或–reverse-sort:反轉排序的順序(例如,升序變爲降序)。
  • –size-sort:按大小排列符號順序。該大小是按照一個符號的值與它下一個符號的值進行計算的。
  • –target=bfdname:指定一個目標代碼的格式,而非使用系統的默認格式。
  • -u或–undefined-only:僅顯示沒有定義的符號(那些外部符號)。
  • –defined-only:僅顯示定義的符號。
  • -l或–line-numbers:對每一個符號,使用調試信息來試圖找到文件名和行號。
  • -V或–version:顯示nm的版本號。
  • –help:顯示nm的選項。

15.2. 符號說明

對於每個符號來講,其類型若是是小寫的,則代表該符號是local的;大寫則代表該符號是global(external)的。

  • A 該符號的值是絕對的,在之後的連接過程當中,不容許進行改變。這樣的符號值,經常出如今中斷向量表中,例如用符號來表示各個中斷向量函數在中斷向量表中的位置。
  • B 該符號的值出如今非初始化數據段(bss)中。例如,在一個文件中定義全局static int test。則該符號test的類型爲b,位於bss section中。其值表示該符號在bss段中的偏移。通常而言,bss段分配於RAM中。
  • C 該符號爲common。common symbol是未初始話數據段。該符號沒有包含於一個普通section中。只有在連接過程當中才進行分配。符號的值表示該符號須要的字節數。例如在一個c文件中,定義int test,而且該符號在別的地方會被引用,則該符號類型即爲C。不然其類型爲B。
  • D 該符號位於初始化數據段中。通常來講,分配到data section中。
    例如:定義全局int baud_table[5] = {9600, 19200, 38400, 57600, 115200},會分配到初始化數據段中。
  • G 該符號也位於初始化數據段中。主要用於small object提升訪問small data object的一種方式。
  • I 該符號是對另外一個符號的間接引用。
  • N 該符號是一個debugging符號。
  • R 該符號位於只讀數據區。
    • 例如定義全局const int test[] = {123, 123};則test就是一個只讀數據區的符號。
    • 值得注意的是,若是在一個函數中定義const char *test = 「abc」, const char test_int = 3。使用nm都不會獲得符號信息,可是字符串」abc」分配於只讀存儲器中,test在rodata section中,大小爲4。
  • S 符號位於非初始化數據區,用於small object。
  • T 該符號位於代碼區text section。
  • U 該符號在當前文件中是未定義的,即該符號的定義在別的文件中。
    例如,當前文件調用另外一個文件中定義的函數,在這個被調用的函數在當前就是未定義的;可是在定義它的文件中類型是T。可是對於全局變量來講,在定義它的文件中,其符號類型爲C,在使用它的文件中,其類型爲U。
  • V 該符號是一個weak object。
  • W The symbol is a weak symbol that has not been specifically tagged as a weak object symbol.
  • ? 該符號類型沒有定義

庫或對象名 若是您指定了 -A 選項,則 nm 命令只報告與該文件有關的或者庫或者對象名。

15.3. 示例

  1. 尋找特殊標識

有時會碰到一個編譯了但沒有連接的代碼,那是由於它缺失了標識符;這種狀況,能夠用nm和objdump、readelf命令來查看程序的符號表;全部這些命令作的工做基本同樣;

好比鏈接器報錯有未定義的標識符;大多數狀況下,會發生在庫的缺失或企圖連接一個錯誤版本的庫的時候;瀏覽目標代碼來尋找一個特殊標識符的引用:

nm -uCA *.o | grep foo

-u選項限制了每一個目標文件中未定義標識符的輸出。-A選項用於顯示每一個標識符的文件名信息;對於C++代碼,經常使用的還有-C選項,它也爲解碼這些標識符;

註解

objdump、readld命令能夠完成一樣的任務。等效命令爲: $objdump -t $readelf -s

  1. 列出 a.out 對象文件的靜態和外部符:

    $nm -e a.out
  2. 以十六進制顯示符號大小和值而且按值排序符號:

    $nm -xv a.out
  3. 顯示 libc.a 中全部 64 位對象符號,忽略全部 32 位對象:

    $nm -X64 /usr/lib/libc.a

    16. size 查看程序內存映像大小

    做用:查看程序被映射到內存中的映像所佔用的大小信息。

    程序映射到內存中,從低地址到高地址依次爲下列段:

    • 代碼段: 只讀,可共享; 代碼段(code segment/text segment )一般是指用來存放程序執行代碼的一塊內存區域。這部分區域的大小在程序運行前就已經肯定,而且內存區域一般屬於只讀, 某些架構也容許代碼段爲可寫,即容許修改程序。在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。
    • 數據段: 儲存已被初始化了的靜態數據。數據段(data segment )一般是指用來存放程序中已初始化的全局變量的一塊內存區域。數據段屬於靜態內存分配。
    • BSS 段:未初始化的數據段. BSS 段(bss segment )一般是指用來存放程序中未初始化的全局變量的一塊內存區域。BSS 是英文Block Started by Symbol 的簡稱。BSS 段屬於靜態內存分配。
    • 堆(heap ): 堆是用於存放進程運行中被動態分配的內存段,它的大小並不固定,可動態擴張或縮減。當進程調用malloc 等函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);當利用free 等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減)
    • 棧(stack) :棧又稱堆棧,是用戶存放程序臨時建立的局部變量,也就是說咱們函數括弧「{} 」中定義的變量(但不包括static 聲明的變量,static 意味着在數據段中存放變量)。除此之外,在函數被調用時,其參數也會被壓入發起調用的進程棧中,而且待到調用結束後,函數的返回值也會被存放回棧中。因爲棧的先進先出特色,因此棧特別方便用來保存/ 恢復調用現場。從這個意義上講,咱們能夠把堆棧當作一個寄存、交換臨時數據的內存區。

    另外, 在高地址還儲存了命令行參數及環境變量.

    由於內存程序映像中的各段可能位於不一樣的地址空間中, 它們不必定位於連續的內存塊中. 操做系統將程序映像映射到地址空間時, 一般將內存程序映像劃分爲大小相同的塊(也就是page, 頁). 只有該頁被引用時, 它才被加載到內存中. 不過對於程序員來講, 能夠視內存程序映像在邏輯上是連續的.

    /opt/app/todeav1/colin/tests#size main
    text    data     bss     dec     hex filename
    1259     540      16    1815     717 main

    關於程序內存映像,這篇文章講的很好:http://blog.chinaunix.net/uid-9012903-id-2011435.html

17. wget 文件下載

Linux系統中的wget是一個下載文件的工具,它用在命令行下。對於Linux用戶是必不可少的工具,咱們常常要下載一些軟件或從遠程服務器恢復備份到本地服務器。wget支持HTTP,HTTPS和FTP協議,可使用HTTP代理。

wget 能夠跟蹤HTML頁面上的連接依次下載來建立遠程服務器的本地版本,徹底重建原始站點的目錄結構。這又常被稱做」遞歸下載」。在遞歸下載的時候,wget 遵循Robot Exclusion標準(/robots.txt). wget能夠在下載的同時,將連接轉換成指向本地文件,以方便離線瀏覽。

wget 很是穩定,它在帶寬很窄的狀況下和不穩定網絡中有很強的適應性.若是是因爲網絡的緣由下載失敗,wget會不斷的嘗試,直到整個文件下載完畢。若是是服務器打斷下載過程,它會再次聯到服務器上從中止的地方繼續下載。這對從那些限定了連接時間的服務器上下載大文件很是有用。

17.1. 命令格式

wget [參數] [URL地址]

17.2. 命令參數:

啓動參數:

  • -V, –version 顯示wget的版本後退出
  • -h, –help 打印語法幫助
  • -b, –background 啓動後轉入後臺執行
  • -e, –execute=COMMAND 執行’.wgetrc’格式的命令,wgetrc格式參見/etc/wgetrc或~/.wgetrc

記錄和輸入文件參數

  • -o, –output-file=FILE 把記錄寫到FILE文件中
  • -a, –append-output=FILE 把記錄追加到FILE文件中
  • -d, –debug 打印調試輸出
  • -q, –quiet 安靜模式(沒有輸出)
  • -v, –verbose 冗長模式(這是缺省設置)
  • -nv, –non-verbose 關掉冗長模式,但不是安靜模式
  • -i, –input-file=FILE 下載在FILE文件中出現的URLs
  • -F, –force-html 把輸入文件看成HTML格式文件對待
  • -B, –base=URL 將URL做爲在-F -i參數指定的文件中出現的相對連接的前綴

–sslcertfile=FILE 可選客戶端證書 –sslcertkey=KEYFILE 可選客戶端證書的KEYFILE –egd-file=FILE 指定EGD socket的文件名

下載參數

  • -bind-address=ADDRESS 指定本地使用地址(主機名或IP,當本地有多個IP或名字時使用)
  • -t, –tries=NUMBER 設定最大嘗試連接次數(0 表示無限制).
  • -O –output-document=FILE 把文檔寫到FILE文件中
  • -nc, –no-clobber 不要覆蓋存在的文件或使用.#前綴
  • -c, –continue 接着下載沒下載完的文件
  • -progress=TYPE 設定進程條標記
  • -N, –timestamping 不要從新下載文件除非比本地文件新
  • -S, –server-response 打印服務器的迴應
  • -T, –timeout=SECONDS 設定響應超時的秒數
  • -w, –wait=SECONDS 兩次嘗試之間間隔SECONDS秒
  • -waitretry=SECONDS 在從新連接之間等待1…SECONDS秒
  • -random-wait 在下載之間等待0…2*WAIT秒
  • -Y, -proxy=on/off 打開或關閉代理
  • -Q, -quota=NUMBER 設置下載的容量限制
  • -limit-rate=RATE 限定下載輸率

目錄參數

  • -nd –no-directories 不建立目錄
  • -x, –force-directories 強制建立目錄
  • -nH, –no-host-directories 不建立主機目錄
  • -P, –directory-prefix=PREFIX 將文件保存到目錄 PREFIX/…
  • -cut-dirs=NUMBER 忽略 NUMBER層遠程目錄

HTTP 選項參數

  • -http-user=USER 設定HTTP用戶名爲 USER.
  • -http-passwd=PASS 設定http密碼爲 PASS
  • -C, –cache=on/off 容許/不容許服務器端的數據緩存 (通常狀況下容許)
  • -E, –html-extension 將全部text/html文檔以.html擴展名保存
  • -ignore-length 忽略 ‘Content-Length’頭域
  • -header=STRING 在headers中插入字符串 STRING
  • -proxy-user=USER 設定代理的用戶名爲 USER
  • proxy-passwd=PASS 設定代理的密碼爲 PASS
  • referer=URL 在HTTP請求中包含 ‘Referer: URL’頭
  • -s, –save-headers 保存HTTP頭到文件
  • -U, –user-agent=AGENT 設定代理的名稱爲 AGENT而不是 Wget/VERSION
  • no-http-keep-alive 關閉 HTTP活動連接 (永遠連接)
  • cookies=off 不使用 cookies
  • load-cookies=FILE 在開始會話前從文件 FILE中加載cookie
  • save-cookies=FILE 在會話結束後將 cookies保存到 FILE文件中

FTP 選項參數

  • -nr, –dont-remove-listing 不移走 ‘.listing’文件
  • -g, –glob=on/off 打開或關閉文件名的 globbing機制
  • passive-ftp 使用被動傳輸模式 (缺省值).
  • active-ftp 使用主動傳輸模式
  • retr-symlinks 在遞歸的時候,將連接指向文件(而不是目錄)

遞歸下載參數

  • -r, –recursive 遞歸下載--慎用!
  • -l, –level=NUMBER 最大遞歸深度 (inf 或 0 表明無窮)
  • -delete-after 在如今完畢後局部刪除文件
  • -k, –convert-links 轉換非相對連接爲相對連接
  • -K, –backup-converted 在轉換文件X以前,將之備份爲 X.orig
  • -m, –mirror 等價於 -r -N -l inf -nr
  • -p, –page-requisites 下載顯示HTML文件的全部圖片
    遞歸下載中的包含和不包含(accept/reject):
  • -A, –accept=LIST 分號分隔的被接受擴展名的列表
  • -R, –reject=LIST 分號分隔的不被接受的擴展名的列表
  • -D, –domains=LIST 分號分隔的被接受域的列表
  • -exclude-domains=LIST 分號分隔的不被接受的域的列表
  • -follow-ftp 跟蹤HTML文檔中的FTP連接
  • -follow-tags=LIST 分號分隔的被跟蹤的HTML標籤的列表
  • -G, –ignore-tags=LIST 分號分隔的被忽略的HTML標籤的列表
  • -H, –span-hosts 當遞歸時轉到外部主機
  • -L, –relative 僅僅跟蹤相對連接
  • -I, –include-directories=LIST 容許目錄的列表
  • -X, –exclude-directories=LIST 不被包含目錄的列表
  • -np, –no-parent 不要追溯到父目錄

wget -S –spider url 不下載只顯示過程

17.3. 使用實例

實例1:使用wget下載單個文件

$wget http://www.minjieren.com/wordpress-3.1-zh_CN.zip

說明:以上例子從網絡下載一個文件並保存在當前目錄,在下載的過程當中會顯示進度條,包含(下載完成百分比,已經下載的字節,當前下載速度,剩餘下載時間)。

實例2:使用wget -O下載並以不一樣的文件名保存

$wget -O wordpress.zip http://www.minjieren.com/download.aspx?id=1080

wget默認會以最後一個符合」/」的後面的字符來命令,對於動態連接的下載一般文件名會不正確。

實例3:使用wget –limit -rate限速下載

$wget --limit-rate=300k http://www.minjieren.com/wordpress-3.1-zh_CN.zip

當你執行wget的時候,它默認會佔用所有可能的寬帶下載。可是當你準備下載一個大文件,而你還須要下載其它文件時就有必要限速了。

實例4:使用wget -c斷點續傳

$wget -c http://www.minjieren.com/wordpress-3.1-zh_CN.zip

使用wget -c從新啓動下載中斷的文件,對於咱們下載大文件時忽然因爲網絡等緣由中斷很是有幫助,咱們能夠繼續接着下載而不是從新下載一個文件。須要繼續中斷的下載時可使用-c參數。

實例5:使用wget -b後臺下載

$wget -b http://www.minjieren.com/wordpress-3.1-zh_CN.zip
Continuing in background, pid 1840.
Output will be written to 'wget-log'.

對於下載很是大的文件的時候,咱們可使用參數-b進行後臺下載。

你可使用如下命令來察看下載進度:

$tail -f wget-log

實例6:假裝代理名稱下載

wget --user-agent="Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16" http://www.minjieren.com/wordpress-3.1-zh_CN.zip

有些網站能經過根據判斷代理名稱不是瀏覽器而拒絕你的下載請求。不過你能夠經過–user-agent參數假裝。

實例7:使用wget -i下載多個文件

首先,保存一份下載連接文件,接着使用這個文件和參數-i下載:

$cat > filelist.txt
url1
url2
url3
url4

$wget -i filelist.txt

實例8:使用wget –mirror鏡像網站

$wget --mirror -p --convert-links -P ./LOCAL URL
下載整個網站到本地
  • -miror:開戶鏡像下載
  • -p:下載全部爲了html頁面顯示正常的文件
  • -convert-links:下載後,轉換成本地的連接
  • -P ./LOCAL:保存全部文件和目錄到本地指定目錄

實例9: 使用wget -r -A下載指定格式文件

$wget -r -A.pdf url
能夠在如下狀況使用該功能:
  • 下載一個網站的全部圖片
  • 下載一個網站的全部視頻
  • 下載一個網站的全部PDF文件

實例10:使用wget FTP下載

$wget ftp-url
$wget --ftp-user=USERNAME --ftp-password=PASSWORD url
可使用wget來完成ftp連接的下載
  • 使用wget匿名ftp下載:wget ftp-url
  • 使用wget用戶名和密碼認證的ftp下載:wget –ftp-user=USERNAME –ftp-password=PASSWORD url

17.4. 編譯安裝

使用以下命令編譯安裝:

tar zxvf wget-1.9.1.tar.gz
cd wget-1.9.1
./configure
make
make install

18. scp 跨機遠程拷貝

scp是secure copy的簡寫,用於在Linux下進行遠程拷貝文件的命令,和它相似的命令有cp,不過cp只是在本機進行拷貝不能跨服務器,並且scp傳輸是加密的。當你服務器硬盤變爲只讀 read only system時,用scp能夠幫你把文件移出來。

註解

相似的工具備rsync;scp消耗資源少,不會提升多少系統負荷,在這一點上,rsync就遠遠不及它了。rsync比scp會快一點,但當小文件多的狀況下,rsync會致使硬盤I/O很是高,而scp基本不影響系統正常使用。

18.1. 命令格式:

scp [參數] [原路徑] [目標路徑]

18.2. 命令參數:

  • -1 強制scp命令使用協議ssh1
  • -2 強制scp命令使用協議ssh2
  • -4 強制scp命令只使用IPv4尋址
  • -6 強制scp命令只使用IPv6尋址
  • -B 使用批處理模式(傳輸過程當中不詢問傳輸口令或短語)
  • -C 容許壓縮。(將-C標誌傳遞給ssh,從而打開壓縮功能)
  • -p 留原文件的修改時間,訪問時間和訪問權限。
  • -q 不顯示傳輸進度條。
  • -r 遞歸複製整個目錄。
  • -v 詳細方式顯示輸出。scp和ssh(1)會顯示出整個過程的調試信息。這些信息用於調試鏈接,驗證和配置問題。
  • -c cipher 以cipher將數據傳輸進行加密,這個選項將直接傳遞給ssh。
  • -F ssh_config 指定一個替代的ssh配置文件,此參數直接傳遞給ssh。
  • -i identity_file 從指定文件中讀取傳輸時使用的密鑰文件,此參數直接傳遞給ssh。
  • -l limit 限定用戶所能使用的帶寬,以Kbit/s爲單位。
  • -o ssh_option 若是習慣於使用ssh_config(5)中的參數傳遞方式,
  • -P port 注意是大寫的P, port是指定數據傳輸用到的端口號
  • -S program 指定加密傳輸時所使用的程序。此程序必須可以理解ssh(1)的選項。

18.3. 使用說明

從本地服務器複製到遠程服務器

複製文件:

$scp local_file remote_username@remote_ip:remote_folder
$scp local_file remote_username@remote_ip:remote_file
$scp local_file remote_ip:remote_folder
$scp local_file remote_ip:remote_file

指定了用戶名,命令執行後須要輸入用戶密碼;若是不指定用戶名,命令執行後須要輸入用戶名和密碼;

複製目錄:

$scp -r local_folder remote_username@remote_ip:remote_folder
$scp -r local_folder remote_ip:remote_folder

第1個指定了用戶名,命令執行後須要輸入用戶密碼; 第2個沒有指定用戶名,命令執行後須要輸入用戶名和密碼;

註解

從遠程複製到本地的scp命令與上面的命令同樣,只要將從本地複製到遠程的命令後面2個參數互換順序就好了。

18.4. 使用示例

實例1:從遠處複製文件到本地目錄

$scp root@10.6.159.147:/opt/soft/demo.tar /opt/soft/

說明: 從10.6.159.147機器上的/opt/soft/的目錄中下載demo.tar 文件到本地/opt/soft/目錄中

實例2:從遠處複製到本地

$scp -r root@10.6.159.147:/opt/soft/test /opt/soft/

說明: 從10.6.159.147機器上的/opt/soft/中下載test目錄到本地的/opt/soft/目錄來。

實例3:上傳本地文件到遠程機器指定目錄

$scp /opt/soft/demo.tar root@10.6.159.147:/opt/soft/scptest

說明: 複製本地opt/soft/目錄下的文件demo.tar 到遠程機器10.6.159.147的opt/soft/scptest目錄

實例4:上傳本地目錄到遠程機器指定目錄

$scp -r /opt/soft/test root@10.6.159.147:/opt/soft/scptest

說明: 上傳本地目錄 /opt/soft/test到遠程機器10.6.159.147上/opt/soft/scptest的目錄中

19. crontab 定時任務

經過crontab 命令,咱們能夠在固定的間隔時間執行指定的系統指令或 shell script腳本。時間間隔的單位能夠是分鐘、小時、日、月、周及以上的任意組合。這個命令很是適合週期性的日誌分析或數據備份等工做。

19.1. 命令格式

crontab [-u user] file crontab [-u user] [ -e | -l | -r ]

19.2. 命令參數

  • -u user:用來設定某個用戶的crontab服務;
  • file:file是命令文件的名字,表示將file作爲crontab的任務列表文件並載入crontab。若是在命令行中沒有指定這個文件,crontab命令將接受標準輸入(鍵盤)上鍵入的命令,並將它們載入crontab。
  • -e:編輯某個用戶的crontab文件內容。若是不指定用戶,則表示編輯當前用戶的crontab文件。
  • -l:顯示某個用戶的crontab文件內容,若是不指定用戶,則表示顯示當前用戶的crontab文件內容。
  • -r:從/var/spool/cron目錄中刪除某個用戶的crontab文件,若是不指定用戶,則默認刪除當前用戶的crontab文件。
  • -i:在刪除用戶的crontab文件時給確認提示。

19.3. crontab的文件格式

分 時 日 月 星期 要運行的命令

  • 第1列分鐘0~59
  • 第2列小時0~23(0表示子夜)
  • 第3列日1~31
  • 第4列月1~12
  • 第5列星期0~7(0和7表示星期天)
  • 第6列要運行的命令

19.4. 經常使用方法

建立一個新的crontab文件

向cron進程提交一個crontab文件以前,首先要設置環境變量EDITOR。cron進程根據它來肯定使用哪一個編輯器編輯crontab文件。9 9 %的UNIX和LINUX用戶都使用vi,若是你也是這樣,那麼你就編輯$HOME目錄下的. profile文件,在其中加入這樣一行:

EDITOR=vi; export EDITOR

而後保存並退出。不妨建立一個名爲<user> cron的文件,其中<user>是用戶名,例如, davecron。在該文件中加入以下的內容。

# (put your own initials here)echo the date to the console every
# 15minutes between 6pm and 6am
0,15,30,45 18-06 * * * /bin/echo 'date' > /dev/console

保存並退出。注意前面5個域用空格分隔。

在上面的例子中,系統將每隔1 5分鐘向控制檯輸出一次當前時間。若是系統崩潰或掛起,從最後所顯示的時間就能夠一眼看出系統是什麼時間中止工做的。在有些系統中,用tty1來表示控制檯,能夠根據實際狀況對上面的例子進行相應的修改。爲了提交你剛剛建立的crontab文件,能夠把這個新建立的文件做爲cron命令的參數:

$ crontab davecron

如今該文件已經提交給cron進程,它將每隔1 5分鐘運行一次。同時,新建立文件的一個副本已經被放在/var/spool/cron目錄中,文件名就是用戶名(即dave)。

列出crontab文件

使用-l參數列出crontab文件:

$ crontab -l
0,15,30,45 18-06 * * * /bin/echo `date` > dev/tty1

可使用這種方法在$HOME目錄中對crontab文件作一備份:

$ crontab -l > $HOME/mycron

這樣,一旦不當心誤刪了crontab文件,能夠用上一節所講述的方法迅速恢復。

編輯crontab文件

若是但願添加、刪除或編輯crontab文件中的條目,而EDITOR環境變量又設置爲vi,那麼就能夠用vi來編輯crontab文件:

$ crontab -e

能夠像使用vi編輯其餘任何文件那樣修改crontab文件並退出。若是修改了某些條目或添加了新的條目,那麼在保存該文件時, cron會對其進行必要的完整性檢查。若是其中的某個域出現了超出容許範圍的值,它會提示你。 咱們在編輯crontab文件時,沒準會加入新的條目。例如,加入下面的一條:

# DT:delete core files,at 3.30am on 1,7,14,21,26,26 days of each month
30 3 1,7,14,21,26 * * /bin/find -name 'core' -exec rm {} \;

保存並退出。

註解

最好在crontab文件的每個條目之上加入一條註釋,這樣就能夠知道它的功能、運行時間,更爲重要的是,知道這是哪位用戶的定時做業。

刪除crontab文件

$crontab -r

19.5. 使用實例

實例1:每1分鐘執行一次myCommand

* * * * * myCommand

實例2:每小時的第3和第15分鐘執行

3,15 * * * * myCommand

實例3:在上午8點到11點的第3和第15分鐘執行

3,15 8-11 * * * myCommand

實例4:每隔兩天的上午8點到11點的第3和第15分鐘執行

3,15 8-11 */2  *  * myCommand

實例5:每週一上午8點到11點的第3和第15分鐘執行

3,15 8-11 * * 1 myCommand

實例6:每晚的21:30重啓smb

30 21 * * * /etc/init.d/smb restart

實例7:每個月一、十、22日的4 : 45重啓smb

45 4 1,10,22 * * /etc/init.d/smb restart

實例8:每週6、週日的1 : 10重啓smb

10 1 * * 6,0 /etc/init.d/smb restart

實例9:天天18 : 00至23 : 00之間每隔30分鐘重啓smb

0,30 18-23 * * * /etc/init.d/smb restart

實例10:每星期六的晚上11 : 00 pm重啓smb

0 23 * * 6 /etc/init.d/smb restart

實例11:每一小時重啓smb

* */1 * * * /etc/init.d/smb restart

實例12:晚上11點到早上7點之間,每隔一小時重啓smb

0 23-7 * * * /etc/init.d/smb restart

19.6. 使用注意事項

注意環境變量問題

有時咱們建立了一個crontab,可是這個任務卻沒法自動執行,而手動執行這個任務卻沒有問題,這種狀況通常是因爲在crontab文件中沒有配置環境變量引發的。

在crontab文件中定義多個調度任務時,須要特別注環境變量的設置,由於咱們手動執行某個任務時,是在當前shell環境下進行的,程序固然能找到環境變量,而系統自動執行任務調度時,是不會加載任何環境變量的,所以,就須要在crontab文件中指定任務運行所需的全部環境變量,這樣,系統執行任務調度時就沒有問題了。

不要假定cron知道所須要的特殊環境,它其實並不知道。因此你要保證在shelll腳本中提供全部必要的路徑和環境變量,除了一些自動設置的全局變量。因此注意以下3點:

  1. 腳本中涉及文件路徑時寫全局路徑;

  2. 腳本執行要用到java或其餘環境變量時,經過source命令引入環境變量,如:

    cat start_cbp.sh
    !/bin/sh
    source /etc/profile
    export RUN_CONF=/home/d139/conf/platform/cbp/cbp_jboss.conf
    /usr/local/jboss-4.0.5/bin/run.sh -c mev &
  3. 當手動執行腳本OK,可是crontab死活不執行時,極可能是環境變量惹的禍,可嘗試在crontab中直接引入環境變量解決問題。如:

    0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh

注意清理系統用戶的郵件日誌

每條任務調度執行完畢,系統都會將任務輸出信息經過電子郵件的形式發送給當前系統用戶,這樣日積月累,日誌信息會很是大,可能會影響系統的正常運行,所以,將每條任務進行重定向處理很是重要。 例如,能夠在crontab文件中設置以下形式,忽略日誌輸出:

0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1

「/dev/null 2>&1」表示先將標準輸出重定向到/dev/null,而後將標準錯誤重定向到標準輸出,因爲標準輸出已經重定向到了/dev/null,所以標準錯誤也會重定向到/dev/null,這樣日誌輸出問題就解決了。

系統級任務調度與用戶級任務調度

系統級任務調度主要完成系統的一些維護操做,用戶級任務調度主要完成用戶自定義的一些任務,能夠將用戶級任務調度放到系統級任務調度來完成(不建議這麼作),可是反過來卻不行,root用戶的任務調度操做能夠經過」crontab –uroot –e」來設置,也能夠將調度任務直接寫入/etc/crontab文件,須要注意的是,若是要定義一個定時重啓系統的任務,就必須將任務放到/etc/crontab文件,即便在root用戶下建立一個定時重啓系統的任務也是無效的。

其餘注意事項

新建立的cron job,不會立刻執行,至少要過2分鐘才執行。若是重啓cron則立刻執行。

當crontab失效時,能夠嘗試/etc/init.d/crond restart解決問題。或者查看日誌看某個job有沒有執行/報錯tail -f /var/log/cron。

千萬別亂運行crontab -r。它從Crontab目錄(/var/spool/cron)中刪除用戶的Crontab文件。刪除了該用戶的全部crontab都沒了。

在crontab中%是有特殊含義的,表示換行的意思。若是要用的話必須進行轉義%,如常常用的date ‘+%Y%m%d’在crontab裏是不會執行的,應該換成date ‘+%Y%m%d’。

更新系統時間時區後須要重啓cron,在ubuntu中服務名爲cron:

$service cron restart

ubuntu下啓動、中止與重啓cron:

$sudo /etc/init.d/cron start
$sudo /etc/init.d/cron stop
$sudo /etc/init.d/cron restart
相關文章
相關標籤/搜索