每個Linux使用者都應該瞭解的命令列省時技巧

jobbole發表於2014-01-07

  有網友在問答網站Quora上提問:“有哪些省時小技巧,是每個Linux使用者都應該知道的?” Joshua Levy 平常就在 Linux 平臺工作,並且他積累了不少實用命令列技巧,他在回覆中精選出一部分。對技術使用者來說,這些技巧挺重要或實用,但知道的人並不多。下文略有點長,一般來說,使用者也不需要對全部內容都瞭解,但為了達到省時方便的目的,Joshua Levy  仍不遺餘力做了校對,以保證列出的每一條都值得一讀,前提是你是一位Linux重度使用者。

  為了獲取文中提到的一個命令的更多資訊,先試下“man <命令名稱>”,在一些情況下,為了讓這條命令可以正常執行,你必須安裝相應的包,可以用aptitude 或者 yum。如果失敗了,求助Google。

 基礎篇

  • 學習基礎的Bash。事實上,讀整個的bash的幫助手冊;很容易理解而且篇幅也不算長。其他一些可選的shell外觀可能更漂亮,但是bash功能很強大而且總是能用(主要學習zsh或者tcsh在很多情況下你會收到限制)。
  • 學習vim,對於Linux下的隨機編輯,幾乎沒有工具能出其右(即使你大部分的時間裡都在使用Emacs或者Eclipse)。
  • 瞭解ssh,以及跳過每次登陸時密碼驗證的基礎辦法,通過ssh-agent,ssh-add等命令。
  • 熟悉bash下的工作管理: &,Ctrl-Z,Ctrl-C,jobs,fg,bg,kill, 等等。
  • 基礎的檔案管理:ls 以及 ls -l (特別的,學習”ls -l”中列出的每一列欄位的含義),less,head,tail,tail -f,ln,ln -s (學習軟連結和硬連結的區別),chown,chmod,du(快速瞭解磁碟總體佔用情況),df,mount。
  • 基礎的網路管理命令:ip 或者 ifconfig,dig。
  • 瞭解正規表示式,以及grep、egrep的不同命令選項,-0,-A,-B 都值得了解一下。
  • 學習使用apt-get 或者 yum(取決於你的發行包)來找到並安裝你需要的包.

 日常使用篇

  • 使用bash時,用Ctrl-R來搜尋命令的歷史記錄。
  • 使用bash時,用Ctrl-W來清除最後一個單詞,使用Ctrl-U來清除整行。可以檢視man readline來獲取bash裡面預設鍵的繫結設定。內容很多。比如Alt-.(注:點)遍歷之前命令中使用過的引數,Alt-* 擴充套件了引數的匹配模式。
  • 回到上次的工作目錄:cd -。
  • 如果你的命令敲到一半時改變了主意,可以用Alt-#來在命令前面增加一個#,使之成為一行註釋(或者使用Ctrl-A回到命令開頭,然後再鍵入#)。你可以之後再通過搜尋歷史記錄回來。
  • 使用xargs(或者parallel)。它非常強大。注意你能控制每一行(-L)執行多少項,也能控制如何併發(- P)。如果你不太確定它會如你所願的工作,先使用xargs。 再者,-l{} 很有用。例如:
find . -name \*.py | xargs grep some_function
cat hosts | xargs -l{} ssh root@{} hostname
  • pstree -p 可以很方便的顯示整個程式樹。
  • 使用pgrep 和pkill 來通過名字來發現程式或者給程式發訊號(-f選項會有用)。
  • 瞭解你能向程式傳送的訊號種類。比如,要掛起一個程式,使用kill -STOP [程式ID]。要了解整個列表,請參考man 7 signal。
  • 如果你想讓一個後臺程式一直執行,使用nohup or disown 。
  • 通過netstat -lntp 來檢測哪些程式在監聽。同樣可以用lsof。
  • bash指令碼中,使用set -x 來除錯輸出。使用set -e在有錯誤時終止時終止執行。要想嚴格輸出錯誤,可以考慮使用set -o pipefail(雖然這個主題說起來有些複雜)。對於更復雜的指令碼,也可以使用trap。
  • bash指令碼中,子shell(通過寫在括號裡)是一種組織命令的方便的方法。一個很常見的例子是暫時移動到另外一個工作目錄,例如:
#在當前目錄下做一些事情
(cd /一些/另外的/目錄;執行別的操作)
#繼續在原來的目錄下執行
  • 要注意bash中有很多種變數表示式。檢查一個變數是否存在:${name:?錯誤資訊}。例如:如果一個bash指令碼需要一個單變數,只需要寫input_file=${1:?usage: $0 inpute_file}。數值擴充套件:i=$({(i+1)%5})。序列:{1..10}。字串的整理:${var%suffix} 和${var#prefix}。例如:
    if var==foo.pdf, then echo ${var%.pdf}.txt   #會列印"foo.txt"。
  • 通過 <(其他指令),一條命令的輸出可以被當作是一個檔案的內容來對待。 例如,比較本地和遠端的 /etc/hosts 檔案,可以用diff /etc/hosts <(ssh [遠端主機] cat /etc/hosts)。
  • 瞭解bash中的“here documents”,比如 cat <<EOF …
  • bash中,通過 其他指令 > 日誌檔案 2>&1  把標準輸出以及標準錯誤重定向。常見的情況是,為了保證一條指令沒有為標準輸入留下一個開啟的檔案描述符,從而輸出至你當前所在的終端,增加“</dev/null” 也是好的習慣。
  • 用man ascii可以得到一個完整的ASCII表,有對應的16進位制和10進位制的值。
  • 通過ssh連線遠端終端時,使用screen或者dtach 來保持你的session,防止被打斷。在ssh中,瞭解如何使用-L或者-D選項(有時也會用到-R)會很有用處,比如,如果通過從一個遠端的伺服器訪問一個網頁。
  • 優化你的SSH選項也可能管用。比如,下面的.ssh/config 內容在一些網路環境下可以防止連線掉線,當連線到新主機時不需要再次確認,跳轉驗證,並且還使用了壓縮(對在一些低寬頻的連線環境下使用scp時會有幫助)。
TCPKeepAlive=yes
ServerAliveInterval=15
ServerAliveCountMax=6
StrictHostKeyChecking=no
Compression=yes
ForwardAgent=yes

 資料處理篇

  • 把HTML轉成文字:lynx -dump 標準輸入
  • 如果要處理XML,xmlstarlet會很棒。
  • 對於Amazon S3,s3cmd 很方便(雖然還不太成熟,可能會有一些不太好的特性)。
  • 瞭解sort 以及 uniq(包括uniq的 -u 以及 -d 選項)。
  • 瞭解cut,paste,join 來操作文字檔案。許多人使用cut但卻忘了還有join。
  • 當你要在檔案之間做集合的加,減,以及差運算時,用sort/uniq是非常方便的。假如a和b是兩個已經去重的文字檔案,那麼運算起來會很快,而且可以在任意大小的檔案之間執行操作,甚至可以到GB位元組大小。(sort不受記憶體限制,不過如果/tmp 在一個很小的root分割槽的話,你可能需要使用-T選項)
cat a b | sort | uniq > c   # c is a union b
cat a b | sort | uniq -d > c   # c is a intersect b
cat a b b | sort | uniq -u > c   # c is set difference a - b
  • 瞭解本地化會影響到許多命令列的工作,包括排序的順序和效能。多數的linux安裝包會把LANG或者其他一些本地化的變數設定為類似美國英語的一個本地設定。這會讓sort和其他一些命令執行起來慢很多。(注意即使你使用UTF-8編碼的文字,你仍然可以放心的通過ASCII碼的順序來排序,這一點用處很多)為避免i18n拖慢日常的工作,使用傳統的基於位元組的排序順序,使用export LC_ALL=C(實際上,考慮在你的.bashrc里加進去)。
  • 瞭解基本的AWK和sed命令來做簡單的資料處理。例如:對一個文字檔案的第三列的數字求和:awk ‘{x += $3} END {print x}’。 這大概比同等的python速度要快三倍並且程式碼長度也會簡短3倍。
  • 就地替換一個字串在所有檔案裡所有出現的地方。
perl -pi.bak -e 's/old-string/new-string/g' my-files-*.txt
  • 使用shuf來隨機打亂一個檔案中的行或者選擇一個隨機的行。
  • 瞭解sort的各個選項。知道鍵值是如何工作的。特別是,當你要使用 -k1時,要格外注意:1只對第一個欄位排序,-k1則意味著根據整個行排序。
  • 穩定排序(sort  -s)可能會有用。例如,先根據第二個欄位排序,再根據第一個欄位排序時,你可以使用sort -k1,1 | sort -s -k2,2
  • 如果你需要在bash裡的命令列裡寫入一個tab鍵的字面值的話,按Ctrl+V, <tab> 或者$‘\t’ (後者更好,因為你可以複製、貼上)。
  • 對於二進位制檔案,使用hd來進行簡單的匯出16進製表示或者用bvi進行二進位制的編輯。
  • 對於二進位制檔案,strings(還有grep等等)可以讓你發現檔案的位元組位(0101).要對檔案轉編,可以試下iconv,或者如果要使用更高階的用法,試試uconv,它可以支援一些高階的Unicode方面的事情。比如,這條命令可以將重音都小寫,並且去掉(通過擴充套件並且丟掉):
uconv -f utf-8 -t utf-8 -x '::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] >; ::Any-NFC; ' < input.txt > output.txt
  • 要將檔案切片,可以試試split(根據大小切分)或者csplit(根據模式切分)。

 系統除錯篇

  • 對於web除錯來說,curl和curl -l會有用,以及和wget相同的那部分功能。
  • 如果想了解磁碟/cpu/網路的狀態,可以使用iostat,netstat,top(更好一些的話,用htop),以及(尤其是)dstat,對於想快速瞭解系統當前正在發生的事情,非常的方便。如果想了解記憶體當前的狀態,可以使用free以及vmstat,還要了解各項輸出的含義。特別值得一提的是,你要知道“cached”的數值是linux核心保留用來做檔案快取的空間的大小,所以真正可用的有效記憶體是“free”項的對應值。
  • java的系統除錯則完全是另外一回事,但在Sun以及其他的JVM上有一個簡單的技巧,就是你可以執行kill -3 <pid> ,得到一個完整的棧呼叫軌跡以及堆使用的總體情況(包括產生的垃圾回收細節,這裡麵包含有很多的資訊),會被定向到標準錯誤或者日誌。
  • 使用mtr作為更好的網路追蹤,識別網路存在的問題。
  • 要檢視一個磁碟是否是滿的,ncdu要比一般用的“du -sk *”要快。
  • 要檢視哪些socket或者程式在佔用頻寬,試試iftop或者netlogs。
  • ab 工具(隨apache的安裝包一起釋出)對於檢測網路伺服器的效能很有幫助,對於更加複雜的壓力測試,可以試下siege。對於更加嚴重的網路問題的除錯,試試wireshark或者tshark。瞭解strace和ltrace。這在一個程式突然失敗,掛掉,或者崩潰,而你卻不知所措,或者是你想知道程式的整體效能的情況時,會很有幫助。可以注意下-c和-p選項。
  • 瞭解用ldd來檢查共享庫函式等的一些問題。
  • 瞭解如何用gdb連線到一個正在執行的程式,並且得到它的呼叫堆疊。
  • 使用/proc. 對於現場除錯問題會很有幫忙。例如:/proc/cpuinfo, /proc/xxx/cwd, /proc/xxx/exe, /proc/xxx/fd/, /proc/xxx/smaps。
  • 當要除錯過去一段時間內出現的問題時,sar 會有用,它可以顯示過去一段時間內的CPU,記憶體,網路的統計資訊。
  • 對於更深層次的系統效能優化,可以關注下stap(systemtap)或者perf。
  • 當出現了一些很詭異的問題時,可以試下dmesg(比如硬體或者驅動的問題)。

  原文連結: Joshua Levy   翻譯: 伯樂線上 - 高磊

相關文章