Linux 命令行的藝術(shù)
熟練使用命令行是一種常常被忽視拘哨,或被認為難以掌握的技能破加,但實際上枫攀,它會提高你作為工程師的靈活性以及生產(chǎn)力。本文是一份我在 Linux 上工作時荠锭,發(fā)現(xiàn)的一些命令行使用技巧的摘要晚胡。有些技巧非常基礎,而另一些則相當復雜逢艘,甚至晦澀難懂。這篇文章并不長泡仗,但當你能夠熟練掌握這里列出的所有技巧時埋虹,你就學會了很多關(guān)于命令行的東西了。
這篇文章是許多作者和譯者共同的成果娩怎。 這里的部分內(nèi)容?首次?出現(xiàn)?于?Quora搔课, 但已經(jīng)遷移到了 Github,并由眾多高手做出了許多改進。 如果你在本文中發(fā)現(xiàn)了錯誤或者存在可以改善的地方爬泥,請貢獻你的一份力量柬讨。
涵蓋范圍:
這篇文章不僅能幫助剛接觸命令行的新手,而且對具有經(jīng)驗的人也大有裨益袍啡。本文致力于做到覆蓋面廣(涉及所有重要的內(nèi)容)踩官,具體(給出具體的最常用的例子),以及簡潔(避免冗余的內(nèi)容境输,或是可以在其他地方輕松查到的細枝末節(jié))蔗牡。在特定應用場景下,本文的內(nèi)容屬于基本功或者能幫助您節(jié)約大量的時間嗅剖。
本文主要為 Linux 所寫辩越,但在僅限 OS X 系統(tǒng)章節(jié)和僅限 Windows 系統(tǒng)章節(jié)中也包含有對應操作系統(tǒng)的內(nèi)容。除去這兩個章節(jié)外信粮,其它的內(nèi)容大部分均可在其他類 Unix 系統(tǒng)或 OS X黔攒,甚至 Cygwin 中得到應用。
本文主要關(guān)注于交互式 Bash强缘,但也有很多技巧可以應用于其他 shell 和 Bash 腳本當中督惰。
除去“標準的”Unix 命令,本文還包括了一些依賴于特定軟件包的命令(前提是它們具有足夠的價值)旅掂。
注意事項:
為了能在一頁內(nèi)展示盡量多的東西赏胚,一些具體的信息可以在引用的頁面中找到。我們相信機智的你知道如何使用 Google 或者其他搜索引擎來查閱到更多的詳細信息辞友。文中部分命令需要您使用?apt-get栅哀,yum,dnf称龙,pacman留拾,?pip?或?brew(以及其它合適的包管理器)來安裝依賴的程序。
遇到問題的話鲫尊,請嘗試使用?Explain shell?去獲取相關(guān)命令痴柔、參數(shù)、管道等內(nèi)容的解釋疫向。
學習 Bash 的基礎知識咳蔚。具體地,在命令行中輸入?man bash?并至少全文瀏覽一遍; 它理解起來很簡單并且不冗長搔驼。其他的 shell 可能很好用谈火,但 Bash 的功能已經(jīng)足夠強大并且到幾乎總是可用的( 如果你只學習 zsh,fish 或其他的 shell 的話舌涨,在你自己的設備上會顯得很方便糯耍,但過度依賴這些功能會給您帶來不便,例如當你需要在服務器上工作時)。
熟悉至少一個基于文本的編輯器温技。通常而言 Vim (vi) 會是你最好的選擇革为,畢竟在終端中編輯文本時 Vim 是最好用的工具(甚至大部分情況下 Vim 要比 Emacs、大型 IDE 或是炫酷的編輯器更好用)舵鳞。
學會如何使用?man?命令去閱讀文檔震檩。學會使用?apropos?去查找文檔。知道有些命令并不對應可執(zhí)行文件蜓堕,而是在 Bash 內(nèi)置好的抛虏,此時可以使用?help?和?help -d?命令獲取幫助信息。你可以用?type 命令?來判斷這個命令到底是可執(zhí)行文件套才、shell 內(nèi)置命令還是別名嘉蕾。
學會使用?>?和?<?來重定向輸出和輸入,學會使用?|?來重定向管道霜旧。明白?>?會覆蓋了輸出文件而?>>?是在文件末添加。了解標準輸出 stdout 和標準錯誤 stderr儡率。
學會使用通配符?*?(或許再算上???和?[...]) 和引用以及引用中?'?和?"?的區(qū)別(后文中有一些具體的例子)挂据。
熟悉 Bash 中的任務管理工具:&,ctrl-z儿普,ctrl-c崎逃,jobs,fg眉孩,bg个绍,kill?等。
學會使用?ssh?進行遠程命令行登錄浪汪,最好知道如何使用?ssh-agent巴柿,ssh-add?等命令來實現(xiàn)基礎的無密碼認證登錄。
學會基本的文件管理工具:ls?和?ls -l?(了解?ls -l?中每一列代表的意義)死遭,less广恢,head,tail?和?tail -f?(甚至?less +F)呀潭,ln?和?ln -s?(了解硬鏈接與軟鏈接的區(qū)別)钉迷,chown,chmod钠署,du?(硬盤使用情況概述:du -hs *)糠聪。 關(guān)于文件系統(tǒng)的管理,學習?df谐鼎,mount舰蟆,fdisk,mkfs,lsblk夭苗。知道 inode 是什么(與?ls -i?和?df -i?等命令相關(guān))信卡。
學習基本的網(wǎng)絡管理工具:ip?或?ifconfig,dig题造。
學習并使用一種版本控制管理系統(tǒng)傍菇,例如?git。
熟悉正則表達式界赔,學會使用?grep/egrep丢习,它們的參數(shù)中?-i,-o淮悼,-v咐低,-A,-B?和?-C?這些是很常用并值得認真學習的袜腥。
學會使用?apt-get见擦,yum,dnf?或?pacman?(具體使用哪個取決于你使用的 Linux 發(fā)行版)來查找和安裝軟件包羹令。并確保你的環(huán)境中有?pip?來安裝基于 Python 的命令行工具 (接下來提到的部分程序使用?pip?來安裝會很方便)鲤屡。
在 Bash 中,可以通過按?Tab?鍵實現(xiàn)自動補全參數(shù)福侈,使用?ctrl-r?搜索命令行歷史記錄(按下按鍵之后酒来,輸入關(guān)鍵字便可以搜索,重復按下?ctrl-r?會向后查找匹配項肪凛,按下?Enter?鍵會執(zhí)行當前匹配的命令堰汉,而按下右方向鍵會將匹配項放入當前行中,不會直接執(zhí)行伟墙,以便做出修改)翘鸭。
在 Bash 中,可以按下?ctrl-w?刪除你鍵入的最后一個單詞戳葵,ctrl-u?可以刪除行內(nèi)光標所在位置之前的內(nèi)容矮固,alt-b?和?alt-f?可以以單詞為單位移動光標,ctrl-a?可以將光標移至行首譬淳,ctrl-e?可以將光標移至行尾档址,ctrl-k?可以刪除光標至行尾的所有內(nèi)容,ctrl-l?可以清屏邻梆。鍵入?man readline?可以查看 Bash 中的默認快捷鍵守伸。內(nèi)容有很多,例如?alt-.?循環(huán)地移向前一個參數(shù)浦妄,而?alt-* 可以展開通配符尼摹。
你喜歡的話见芹,可以執(zhí)行?set -o vi?來使用 vi 風格的快捷鍵,而執(zhí)行?set -o emacs?可以把它改回來蠢涝。
為了便于編輯長命令玄呛,在設置你的默認編輯器后(例如?export EDITOR=vim),ctrl-x?ctrl-e?會打開一個編輯器來編輯當前輸入的命令和二。在 vi 風格下快捷鍵則是?escape-v徘铝。
鍵入?history?查看命令行歷史記錄,再用?!n(n?是命令編號)就可以再次執(zhí)行惯吕。其中有許多縮寫惕它,最有用的大概就是?!$, 它用于指代上次鍵入的參數(shù)废登,而?!!?可以指代上次鍵入的命令了(參考 man 頁面中的“HISTORY EXPANSION”)淹魄。不過這些功能,你也可以通過快捷鍵?ctrl-r?和?alt-.?來實現(xiàn)堡距。
cd?命令可以切換工作路徑甲锡,輸入?cd ~?可以進入 home 目錄。要訪問你的 home 目錄中的文件羽戒,可以使用前綴?~(例如?~/.bashrc)搔体。在?sh?腳本里則用環(huán)境變量?$HOME?指代 home 目錄的路徑。
回到前一個工作路徑:cd -半醉。
如果你輸入命令的時候中途改了主意,按下?alt-#?在行首添加?#?把它當做注釋再按下回車執(zhí)行(或者依次按下?ctrl-a劝术,?#缩多,?enter)男娄。這樣做的話构眯,之后借助命令行歷史記錄以舒,你可以很方便恢復你剛才輸入到一半的命令赊抖。
使用?xargs?( 或?parallel)疏唾。他們非常給力冠跷。注意到你可以控制每行參數(shù)個數(shù)(-L)和最大并行數(shù)(-P)荡含。如果你不確定它們是否會按你想的那樣工作火窒,先使用?xargs echo?查看一下零酪。此外冒嫡,使用?-I{}?會很方便。例如:
find.-name'*.py'|xargs grep some_function? ? ? cat hosts|xargs -I{} ssh root@{} hostname
pstree -p?以一種優(yōu)雅的方式展示進程樹四苇。
使用?pgrep?和?pkill?根據(jù)名字查找進程或發(fā)送信號(-f?參數(shù)通常有用)孝凌。
了解你可以發(fā)往進程的信號的種類。比如月腋,使用?kill -STOP [pid]?停止一個進程蟀架。使用?man 7 signal?查看詳細列表瓣赂。
使用?nohup?或?disown?使一個后臺進程持續(xù)運行。
使用?netstat -lntp?或?ss -plat?檢查哪些進程在監(jiān)聽端口(默認是檢查 TCP 端口; 添加參數(shù)?-u?則檢查 UDP 端口)或者?lsof -iTCP -sTCP:LISTEN -P -n?(這也可以在 OS X 上運行)片拍。
lsof?來查看開啟的套接字和文件煌集。
使用?uptime?或?w?來查看系統(tǒng)已經(jīng)運行多長時間。
使用?alias?來創(chuàng)建常用命令的快捷形式捌省。例如:alias ll='ls -latr'?創(chuàng)建了一個新的命令別名?ll苫纤。
可以把別名、shell 選項和常用函數(shù)保存在?~/.bashrc所禀,具體看下這篇文章方面。這樣做的話你就可以在所有 shell 會話中使用你的設定。
把環(huán)境變量的設定以及登陸時要執(zhí)行的命令保存在?~/.bash_profile色徘。而對于從圖形界面啟動的 shell 和?cron?啟動的 shell恭金,則需要單獨配置文件。
要想在幾臺電腦中同步你的配置文件(例如?.bashrc?和?.bash_profile)褂策,可以借助 Git横腿。
當變量和文件名中包含空格的時候要格外小心。Bash 變量要用引號括起來斤寂,比如?"$FOO"耿焊。盡量使用?-0?或?-print0?選項以便用 NULL 來分隔文件名,例如?locate -0 pattern | xargs -0 ls -al?或?find / -print0 -type d | xargs -0 ls -al遍搞。如果 for 循環(huán)中循環(huán)訪問的文件名含有空字符(空格罗侯、tab 等字符),只需用?IFS=$'\n'?把內(nèi)部字段分隔符設為換行符溪猿。
在 Bash 腳本中钩杰,使用?set -x?去調(diào)試輸出(或者使用它的變體?set -v,它會記錄原始輸入诊县,包括多余的參數(shù)和注釋)讲弄。盡可能地使用嚴格模式:使用?set -e?令腳本在發(fā)生錯誤時退出而不是繼續(xù)運行;使用?set -u?來檢查是否使用了未賦值的變量依痊;試試?set -o pipefail避除,它可以監(jiān)測管道中的錯誤。當牽扯到很多腳本時胸嘁,使用?trap?來檢測 ERR 和 EXIT瓶摆。一個好的習慣是在腳本文件開頭這樣寫,這會使它能夠檢測一些錯誤性宏,并在錯誤發(fā)生時中斷程序并輸出信息:
set-euo pipefailtrap"echo 'error: Script failed: see failed command above'"ERR
在 Bash 腳本中赏壹,子 shell(使用括號?(...))是一種組織參數(shù)的便捷方式。一個常見的例子是臨時地移動工作路徑衔沼,代碼如下:
#do something in current dir(cd /some/other/dir&&other-command)#continue in original dir
在 Bash 中蝌借,變量有許多的擴展方式昔瞧。${name:?error message}?用于檢查變量是否存在。此外菩佑,當 Bash 腳本只需要一個參數(shù)時自晰,可以使用這樣的代碼?input_file=${1:?usage: $0 input_file}。在變量為空時使用默認值:${name:-default}稍坯。如果你要在之前的例子中再加一個(可選的)參數(shù)酬荞,可以使用類似這樣的代碼?output_file=${2:-logfile},如果省略了 $2瞧哟,它的值就為空混巧,于是?output_file?就會被設為?logfile。數(shù)學表達式:i=$(( (i + 1) % 5 ))勤揩。序列:{1..10}咧党。截斷字符串:${var%suffix}?和?${var#prefix}。例如陨亡,假設?var=foo.pdf傍衡,那么?echo ${var%.pdf}.txt?將輸出?foo.txt。
使用括號擴展({...})來減少輸入相似文本负蠕,并自動化文本組合蛙埂。這在某些情況下會很有用,例如?mv foo.{txt,pdf} some-dir(同時移動兩個文件)遮糖,cp somefile{,.bak}(會被擴展成?cp somefile somefile.bak)或者?mkdir -p test-{a,b,c}/subtest-{1,2,3}(會被擴展成所有可能的組合绣的,并創(chuàng)建一個目錄樹)。
通過使用?<(some command)?可以將輸出視為文件欲账。例如屡江,對比本地文件?/etc/hosts?和一個遠程文件:
diff /etc/hosts<(ssh somehost cat /etc/hosts)
編寫腳本時,你可能會想要把代碼都放在大括號里敬惦。缺少右括號的話,代碼就會因為語法錯誤而無法執(zhí)行谈山。如果你的腳本是要放在網(wǎng)上分享供他人使用的俄删,這樣的寫法就體現(xiàn)出它的好處了,因為這樣可以防止下載不完全代碼被執(zhí)行奏路。
{#在這里寫代碼}
了解 Bash 中的“here documents”畴椰,例如?cat <<EOF ...。
在 Bash 中鸽粉,同時重定向標準輸出和標準錯誤:some-command >logfile 2>&1?或者?some-command &>logfile斜脂。通常,為了保證命令不會在標準輸入里殘留一個未關(guān)閉的文件句柄捆綁在你當前所在的終端上触机,在命令后添加?</dev/null?是一個好習慣帚戳。
使用?man ascii?查看具有十六進制和十進制值的ASCII表玷或。man unicode,man utf-8片任,以及?man latin1?有助于你去了解通用的編碼信息偏友。
使用?screen?或?tmux?來使用多份屏幕,當你在使用 ssh 時(保存 session 信息)將尤為有用对供。而?byobu?可以為它們提供更多的信息和易用的管理工具位他。另一個輕量級的 session 持久化解決方案是?dtach。
ssh 中产场,了解如何使用?-L?或?-D(偶爾需要用?-R)開啟隧道是非常有用的鹅髓,比如當你需要從一臺遠程服務器上訪問 web 頁面。
對 ssh 設置做一些小優(yōu)化可能是很有用的京景,例如這個?~/.ssh/config?文件包含了防止特定網(wǎng)絡環(huán)境下連接斷開窿冯、壓縮數(shù)據(jù)、多通道等選項:
? ? ? TCPKeepAlive=yes
? ? ? ServerAliveInterval=15
? ? ? ServerAliveCountMax=6
? ? ? Compression=yes
? ? ? ControlMaster auto
? ? ? ControlPath /tmp/%r@%h:%p
? ? ? ControlPersist yes
一些其他的關(guān)于 ssh 的選項是與安全相關(guān)的醋粟,應當小心翼翼的使用靡菇。例如你應當只能在可信任的網(wǎng)絡中啟用?StrictHostKeyChecking=no,F(xiàn)orwardAgent=yes米愿。
考慮使用?mosh?作為 ssh 的替代品厦凤,它使用 UDP 協(xié)議。它可以避免連接被中斷并且對帶寬需求更小育苟,但它需要在服務端做相應的配置较鼓。
獲取八進制形式的文件訪問權(quán)限(修改系統(tǒng)設置時通常需要,但?ls?的功能不那么好用并且通常會搞砸)违柏,可以使用類似如下的代碼:
stat -c'%A %a %n'/etc/timezone
使用?percol?或者?fzf?可以交互式地從另一個命令輸出中選取值博烂。
使用?fpp(PathPicker)可以與基于另一個命令(例如?git)輸出的文件交互。
將 web 服務器上當前目錄下所有的文件(以及子目錄)暴露給你所處網(wǎng)絡的所有用戶漱竖,使用:?python -m SimpleHTTPServer 7777?(使用端口 7777 和 Python 2)或python -m http.server 7777?(使用端口 7777 和 Python 3)禽篱。
以其他用戶的身份執(zhí)行命令,使用?sudo馍惹。默認以 root 用戶的身份執(zhí)行躺率;使用?-u?來指定其他用戶。使用?-i?來以該用戶登錄(需要輸入_你自己的_密碼)万矾。
將 shell 切換為其他用戶悼吱,使用?su username?或者?sudo - username。加入?-?會使得切換后的環(huán)境與使用該用戶登錄后的環(huán)境相同良狈。省略用戶名則默認為 root后添。切換到哪個用戶,就需要輸入_哪個用戶的_密碼薪丁。
了解命令行的?128K 限制遇西。使用通配符匹配大量文件名時馅精,常會遇到“Argument list too long”的錯誤信息。(這種情況下?lián)Q用?find?或?xargs?通撑#可以解決硫嘶。)
當你需要一個基本的計算器時,可以使用?python?解釋器(當然你要用 python 的時候也是這樣)梧税。例如:
>>> 2+3
5
在當前目錄下通過文件名查找一個文件沦疾,使用類似于這樣的命令:find . -iname '*something*'。在所有路徑下通過文件名查找文件第队,使用?locate something?(但注意到?updatedb?可能沒有對最近新建的文件建立索引哮塞,所以你可能無法定位到這些未被索引的文件)。
使用?ag?在源代碼或數(shù)據(jù)文件里檢索(grep -r?同樣可以做到凳谦,但相比之下?ag?更加先進)忆畅。
將 HTML 轉(zhuǎn)為文本:lynx -dump -stdin。
Markdown尸执,HTML家凯,以及所有文檔格式之間的轉(zhuǎn)換,試試?pandoc如失。
當你要處理棘手的 XML 時候绊诲,xmlstarlet?算是上古時代流傳下來的神器。
使用?jq?處理 JSON褪贵。
使用?shyaml?處理 YAML掂之。
要處理 Excel 或 CSV 文件的話,csvkit?提供了?in2csv脆丁,csvcut世舰,csvjoin,csvgrep?等方便易用的工具槽卫。
當你要處理 Amazon S3 相關(guān)的工作的時候跟压,s3cmd?是一個很方便的工具而?s4cmd?的效率更高。Amazon 官方提供的?aws?以及?saws?是其他 AWS 相關(guān)工作的基礎歼培,值得學習震蒋。
了解如何使用?sort?和?uniq,包括 uniq 的?-u?參數(shù)和?-d?參數(shù)丐怯,具體內(nèi)容在后文單行腳本節(jié)中喷好。另外可以了解一下?comm翔横。
了解如何使用?cut读跷,paste?和?join?來更改文件。很多人都會使用?cut禾唁,但遺忘了?join效览。
了解如何運用?wc?去計算新行數(shù)(-l)无切,字符數(shù)(-m),單詞數(shù)(-w)以及字節(jié)數(shù)(-c)丐枉。
了解如何使用?tee?將標準輸入復制到文件甚至標準輸出哆键,例如?ls -al | tee file.txt。
要進行一些復雜的計算瘦锹,比如分組籍嘹、逆序和一些其他的統(tǒng)計分析,可以考慮使用?datamash弯院。
注意到語言設置(中文或英文等)對許多命令行工具有一些微妙的影響辱士,比如排序的順序和性能。大多數(shù) Linux 的安裝過程會將?LANG?或其他有關(guān)的變量設置為符合本地的設置听绳。要意識到當你改變語言設置時颂碘,排序的結(jié)果可能會改變。明白國際化可能會使 sort 或其他命令運行效率下降許多倍椅挣。某些情況下(例如集合運算)你可以放心的使用?export LC_ALL=C?來忽略掉國際化并按照字節(jié)來判斷順序头岔。
你可以單獨指定某一條命令的環(huán)境,只需在調(diào)用時把環(huán)境變量設定放在命令的前面鼠证,例如?TZ=Pacific/Fiji date?可以獲取斐濟的時間峡竣。
了解如何使用?awk?和?sed?來進行簡單的數(shù)據(jù)處理。 參閱?One-liners?獲取示例名惩。
替換一個或多個文件中出現(xiàn)的字符串:
perl -pi.bak -e's/old-string/new-string/g'my-files-*.txt
使用?repren?來批量重命名文件澎胡,或是在多個文件中搜索替換內(nèi)容。(有些時候?rename?命令也可以批量重命名娩鹉,但要注意攻谁,它在不同 Linux 發(fā)行版中的功能并不完全一樣。)
#將文件弯予、目錄和內(nèi)容全部重命名 foo -> bar:repren --full --preserve-case --from foo --to bar.#還原所有備份文件 whatever.bak -> whatever:repren --renames --from'(.*)\.bak'--to'\1'*.bak#用 rename 實現(xiàn)上述功能(若可用):rename's/\.bak$//'*.bak
根據(jù) man 頁面的描述戚宦,rsync?是一個快速且非常靈活的文件復制工具。它聞名于設備之間的文件同步锈嫩,但其實它在本地情況下也同樣有用受楼。在安全設置允許下,用?rsync?代替?scp?可以實現(xiàn)文件續(xù)傳呼寸,而不用重新從頭開始艳汽。它同時也是刪除大量文件的最快方法之一:
mkdir empty&&rsync -r --delete empty/ some-dir&&rmdir some-dir
若要在復制文件時獲取當前進度,可使用?pv对雪,pycp河狐,progress,rsync --progress。若所執(zhí)行的復制為block塊拷貝馋艺,可以使用?dd status=progress。
使用?shuf?可以以行為單位來打亂文件的內(nèi)容或從一個文件中隨機選取多行捐祠。
了解?sort?的參數(shù)碱鳞。顯示數(shù)字時,使用?-n?或者?-h?來顯示更易讀的數(shù)(例如?du -h?的輸出)踱蛀。明白排序時關(guān)鍵字的工作原理(-t?和?-k)窿给。例如,注意到你需要?-k1率拒,1?來僅按第一個域來排序填大,而?-k1?意味著按整行排序。穩(wěn)定排序(sort -s)在某些情況下很有用俏橘。例如允华,以第二個域為主關(guān)鍵字,第一個域為次關(guān)鍵字進行排序寥掐,你可以使用?sort -k1靴寂,1 | sort -s -k2,2召耘。
如果你想在 Bash 命令行中寫 tab 制表符百炬,按下?ctrl-v?[Tab]?或鍵入?$'\t'?(后者可能更好,因為你可以復制粘貼它)污它。
標準的源代碼對比及合并工具是?diff?和?patch剖踊。使用?diffstat?查看變更總覽數(shù)據(jù)。注意到?diff -r?對整個文件夾有效衫贬。使用?diff -r tree1 tree2 | diffstat?查看變更的統(tǒng)計數(shù)據(jù)德澈。vimdiff?用于比對并編輯文件。
對于二進制文件固惯,使用?hd梆造,hexdump?或者?xxd?使其以十六進制顯示,使用?bvi葬毫,hexedit?或者?biew?來進行二進制編輯镇辉。
同樣對于二進制文件,strings(包括?grep?等工具)可以幫助在二進制文件中查找特定比特贴捡。
制作二進制差分文件(Delta 壓縮)忽肛,使用?xdelta3。
使用?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(按模式拆分)。
操作日期和時間表達式香缺,可以用?dateutils?中的?dateadd手销、datediff、strptime?等工具图张。
使用?zless锋拖、zmore、zcat?和?zgrep?對壓縮過的文件進行操作祸轮。
文件屬性可以通過?chattr?進行設置兽埃,它比文件權(quán)限更加底層。例如适袜,為了保護文件不被意外刪除柄错,可以使用不可修改標記:sudo chattr +i /critical/directory/or/file
使用?getfacl?和?setfacl?以保存和恢復文件權(quán)限。例如:
getfacl -R /some/path>permissions.txt? setfacl --restore=permissions.txt
為了高效地創(chuàng)建空文件苦酱,請使用?truncate(創(chuàng)建稀疏文件)售貌,fallocate(用于 ext4,xfs疫萤,btrf 和 ocfs2 文件系統(tǒng))颂跨,xfs_mkfile(適用于幾乎所有的文件系統(tǒng),包含在 xfsprogs 包中)扯饶,mkfile(用于類 Unix 操作系統(tǒng)恒削,比如 Solaris 和 Mac OS)。
curl?和?curl -I?可以被輕松地應用于 web 調(diào)試中尾序,它們的好兄弟?wget?也是如此钓丰,或者也可以試試更潮的?httpie。
獲取 CPU 和硬盤的使用狀態(tài)每币,通常使用使用?top(htop?更佳)斑粱,iostat?和?iotop。而?iostat -mxz 15?可以讓你獲悉 CPU 和每個硬盤分區(qū)的基本信息和性能表現(xiàn)脯爪。
使用?netstat?和?ss?查看網(wǎng)絡連接的細節(jié)则北。
dstat?在你想要對系統(tǒng)的現(xiàn)狀有一個粗略的認識時是非常有用的。然而若要對系統(tǒng)有一個深度的總體認識痕慢,使用?glances尚揣,它會在一個終端窗口中向你提供一些系統(tǒng)級的數(shù)據(jù)。
若要了解內(nèi)存狀態(tài)掖举,運行并理解?free?和?vmstat?的輸出快骗。值得留意的是“cached”的值,它指的是 Linux 內(nèi)核用來作為文件緩存的內(nèi)存大小,而與空閑內(nèi)存無關(guān)方篮。
Java 系統(tǒng)調(diào)試則是一件截然不同的事名秀,一個可以用于 Oracle 的 JVM 或其他 JVM 上的調(diào)試的技巧是你可以運行?kill -3 <pid>?同時一個完整的棧軌跡和堆概述(包括 GC 的細節(jié))會被保存到標準錯誤或是日志文件。JDK 中的?jps藕溅,jstat匕得,jstack,jmap?很有用巾表。SJK tools?更高級汁掠。
使用?mtr?去跟蹤路由,用于確定網(wǎng)絡問題集币。
用?ncdu?來查看磁盤使用情況考阱,它比尋常的命令,如?du -sh *鞠苟,更節(jié)省時間乞榨。
查找正在使用帶寬的套接字連接或進程,使用?iftop?或?nethogs当娱。
ab?工具(Apache 中自帶)可以簡單粗暴地檢查 web 服務器的性能姜凄。對于更復雜的負載測試,使用?siege趾访。
wireshark态秧,tshark?和?ngrep?可用于復雜的網(wǎng)絡調(diào)試。
了解?strace?和?ltrace扼鞋。這倆工具在你的程序運行失敗申鱼、掛起甚至崩潰显熏,而你卻不知道為什么或你想對性能有個總體的認識的時候是非常有用的也拜。注意 profile 參數(shù)(-c)和附加到一個運行的進程參數(shù) (-p)。
了解使用?ldd?來檢查共享庫钾菊。但是永遠不要在不信任的文件上運行溃槐。
了解如何運用?gdb?連接到一個運行著的進程并獲取它的堆棧軌跡匣砖。
學會使用?/proc。它在調(diào)試正在出現(xiàn)的問題的時候有時會效果驚人昏滴。比如:/proc/cpuinfo猴鲫,/proc/meminfo,/proc/cmdline谣殊,/proc/xxx/cwd拂共,/proc/xxx/exe,/proc/xxx/fd/姻几,/proc/xxx/smaps(這里的?xxx?表示進程的 id 或 pid)宜狐。
當調(diào)試一些之前出現(xiàn)的問題的時候势告,sar?非常有用。它展示了 cpu抚恒、內(nèi)存以及網(wǎng)絡等的歷史數(shù)據(jù)咱台。
關(guān)于更深層次的系統(tǒng)分析以及性能分析,看看?stap(SystemTap)俭驮,perf回溺,以及sysdig。
查看你當前使用的系統(tǒng)表鳍,使用?uname,uname -a(Unix/kernel 信息)或者?lsb_release -a(Linux 發(fā)行版信息)祥诽。
無論什么東西工作得很歡樂(可能是硬件或驅(qū)動問題)時可以試試?dmesg譬圣。
如果你刪除了一個文件,但通過?du?發(fā)現(xiàn)沒有釋放預期的磁盤空間雄坪,請檢查文件是否被進程占用:?lsof | grep deleted | grep "filename-of-my-big-file"
一些命令組合的例子:
當你需要對文本文件做集合交厘熟、并、差運算時维哈,sort?和?uniq?會是你的好幫手绳姨。具體例子請參照代碼后面的,此處假設?a?與?b?是兩內(nèi)容不同的文件阔挠。這種方式效率很高飘庄,并且在小文件和上 G 的文件上都能運用(注意盡管在?/tmp?在一個小的根分區(qū)上時你可能需要?-T?參數(shù),但是實際上?sort?并不被內(nèi)存大小約束)购撼,參閱前文中關(guān)于?LC_ALL?和?sort?的?-u?參數(shù)的部分跪削。
sort a b|uniq>c#c 是 a 并 bsort a b|uniq -d>c#c 是 a 交 bsort a b b|uniq -u>c#c 是 a - b
使用?grep . *(每行都會附上文件名)或者?head -100 *(每個文件有一個標題)來閱讀檢查目錄下所有文件的內(nèi)容。這在檢查一個充滿配置文件的目錄(如?/sys迂求、/proc碾盐、/etc)時特別好用。
計算文本文件第三列中所有數(shù)的和(可能比同等作用的 Python 代碼快三倍且代碼量少三倍):
awk'{ x += $3 } END { print x }'myfile
如果你想在文件樹上查看大小/日期揩局,這可能看起來像遞歸版的?ls -l?但比?ls -lR?更易于理解:
find.-type f -ls
假設你有一個類似于 web 服務器日志文件的文本文件毫玖,并且一個確定的值只會出現(xiàn)在某些行上,假設一個?acct_id?參數(shù)在 URI 中凌盯。如果你想計算出每個?acct_id?值有多少次請求付枫,使用如下代碼:
egrep -o'acct_id=[0-9]+'access.log|cut -d= -f2|sort|uniq -c|sort -rn
要持續(xù)監(jiān)測文件改動,可以使用?watch驰怎,例如檢查某個文件夾中文件的改變励背,可以用?watch -d -n 2 'ls -rtlh | tail';或者在排查 WiFi 設置故障時要監(jiān)測網(wǎng)絡設置的更改砸西,可以用?watch -d -n 2 ifconfig叶眉。
運行這個函數(shù)從這篇文檔中隨機獲取一條技巧(解析 Markdown 文件并抽取項目):
functiontaocl(){? ? ? ? curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README-zh.md|pandoc -f markdown -t html|iconv -f'utf-8'-t'unicode'|xmlstarlet fo --html --dropdtd|xmlstarlet sel -t -v"(html/body/ul/li[count(p)>0])[$RANDOMmod last()+1]"|xmlstarlet unesc|fmt -80? ? ? }
expr:計算表達式或正則匹配
m4:簡單的宏處理器
yes:多次打印字符串
cal:漂亮的日歷
env:執(zhí)行一個命令(腳本文件中很有用)
printenv:打印環(huán)境變量(調(diào)試時或在寫腳本文件時很有用)
look:查找以特定字符串開頭的單詞或行
cut址儒,paste?和?join:數(shù)據(jù)修改
fmt:格式化文本段落
pr:將文本格式化成頁/列形式
fold:包裹文本中的幾行
column:將文本格式化成多個對齊、定寬的列或表格
expand?和?unexpand:制表符與空格之間轉(zhuǎn)換
nl:添加行號
seq:打印數(shù)字
bc:計算器
factor:分解因數(shù)
gpg:加密并簽名文件
toe:terminfo 入口列表
nc:網(wǎng)絡調(diào)試及數(shù)據(jù)傳輸
socat:套接字代理衅疙,與?netcat?類似
slurm:網(wǎng)絡流量可視化
dd:文件或設備間傳輸數(shù)據(jù)
file:確定文件類型
tree:以樹的形式顯示路徑和文件莲趣,類似于遞歸的?ls
stat:文件信息
time:執(zhí)行命令,并計算執(zhí)行時間
timeout:在指定時長范圍內(nèi)執(zhí)行命令饱溢,并在規(guī)定時間結(jié)束后停止進程
lockfile:使文件只能通過?rm -f?移除
logrotate: 切換喧伞、壓縮以及發(fā)送日志文件
watch:重復運行同一個命令,展示結(jié)果并/或高亮有更改的部分
when-changed:當檢測到文件更改時執(zhí)行指定命令绩郎。參閱?inotifywait?和?entr潘鲫。
tac:反向輸出文件
shuf:文件中隨機選取幾行
comm:一行一行的比較排序過的文件
strings:從二進制文件中抽取文本
tr:轉(zhuǎn)換字母
iconv?或?uconv:文本編碼轉(zhuǎn)換
split?和?csplit:分割文件
sponge:在寫入前讀取所有輸入,在讀取文件后再向同一文件寫入時比較有用肋杖,例如?grep -v something some-file | sponge some-file
units:將一種計量單位轉(zhuǎn)換為另一種等效的計量單位(參閱?/usr/share/units/definitions.units)
apg:隨機生成密碼
xz:高比例的文件壓縮
ldd:動態(tài)庫信息
nm:提取 obj 文件中的符號
ab?或?wrk:web 服務器性能分析
strace:調(diào)試系統(tǒng)調(diào)用
mtr:更好的網(wǎng)絡調(diào)試跟蹤工具
cssh:可視化的并發(fā) shell
rsync:通過 ssh 或本地文件系統(tǒng)同步文件和文件夾
wireshark?和?tshark:抓包和網(wǎng)絡調(diào)試工具
ngrep:網(wǎng)絡層的 grep
host?和?dig:DNS 查找
lsof:列出當前系統(tǒng)打開文件的工具以及查看端口信息
dstat:系統(tǒng)狀態(tài)查看
glances:高層次的多子系統(tǒng)總覽
iostat:硬盤使用狀態(tài)
mpstat: CPU 使用狀態(tài)
vmstat: 內(nèi)存使用狀態(tài)
htop:top 的加強版
last:登入記錄
w:查看處于登錄狀態(tài)的用戶
id:用戶/組 ID 信息
sar:系統(tǒng)歷史數(shù)據(jù)
iftop?或?nethogs:套接字及進程的網(wǎng)絡利用情況
ss:套接字數(shù)據(jù)
dmesg:引導及系統(tǒng)錯誤信息
sysctl: 在內(nèi)核運行時動態(tài)地查看和修改內(nèi)核的運行參數(shù)
hdparm:SATA/ATA 磁盤更改及性能分析
lsblk:列出塊設備信息:以樹形展示你的磁盤以及磁盤分區(qū)信息
lshw溉仑,lscpu,lspci状植,lsusb?和?dmidecode:查看硬件信息浊竟,包括 CPU、BIOS津畸、RAID振定、顯卡、USB設備等
lsmod?和?modinfo:列出內(nèi)核模塊肉拓,并顯示其細節(jié)
fortune后频,ddate?和?sl:額,這主要取決于你是否認為蒸汽火車和莫名其妙的名人名言是否“有用”
以下是僅限于?OS X 系統(tǒng)的技巧暖途。
用?brew?(Homebrew)或者?port?(MacPorts)進行包管理徘郭。這些可以用來在 OS X 系統(tǒng)上安裝以上的大多數(shù)命令。
用?pbcopy?復制任何命令的輸出到桌面應用丧肴,用?pbpaste?粘貼輸入残揉。
若要在 OS X 終端中將 Option 鍵視為 alt 鍵(例如在上面介紹的?alt-b、alt-f?等命令中用到)芋浮,打開 偏好設置 -> 描述文件 -> 鍵盤 并勾選“使用 Option 鍵作為 Meta 鍵”抱环。
用?open?或者?open -a /Applications/Whatever.app?使用桌面應用打開文件。
Spotlight:用?mdfind?搜索文件纸巷,用?mdls?列出元數(shù)據(jù)(例如照片的 EXIF 信息)镇草。
注意 OS X 系統(tǒng)是基于 BSD UNIX 的,許多命令(例如?ps瘤旨,ls梯啤,tail,awk存哲,sed)都和 Linux 中有微妙的不同( Linux 很大程度上受到了 System V-style Unix 和 GNU 工具影響)因宇。你可以通過標題為 "BSD General Commands Manual" 的 man 頁面發(fā)現(xiàn)這些不同七婴。在有些情況下 GNU 版本的命令也可能被安裝(例如?gawk?和?gsed?對應 GNU 中的 awk 和 sed )。如果要寫跨平臺的 Bash 腳本察滑,避免使用這些命令(例如打厘,考慮 Python 或者?perl?)或者經(jīng)過仔細的測試。
用?sw_vers?獲取 OS X 的版本信息贺辰。
以下是僅限于?Windows 系統(tǒng)的技巧户盯。
可以安裝?Cygwin?允許你在 Microsoft Windows 中體驗 Unix shell 的威力。這樣的話饲化,本文中介紹的大多數(shù)內(nèi)容都將適用莽鸭。
在 Windows 10 上,你可以使用?Bash on Ubuntu on Windows吃靠,它提供了一個熟悉的 Bash 環(huán)境硫眨,包含了不少 Unix 命令行工具。好處是它允許 Linux 上編寫的程序在 Windows 上運行撩笆,而另一方面捺球,Windows 上編寫的程序卻無法在 Bash 命令行中運行缸浦。
如果你在 Windows 上主要想用 GNU 開發(fā)者工具(例如 GCC)夕冲,可以考慮?MinGW?以及它的?MSYS?包,這個包提供了例如 bash裂逐,gawk歹鱼,make 和 grep 的工具。MSYS 并不包含所有可以與 Cygwin 媲美的特性卜高。當制作 Unix 工具的原生 Windows 端口時 MinGW 將特別地有用弥姻。
另一個在 Windows 下實現(xiàn)接近 Unix 環(huán)境外觀效果的選項是?Cash。注意在此環(huán)境下只有很少的 Unix 命令和命令行可用掺涛。
可以使用?wmic?在命令行環(huán)境下給大部分 Windows 系統(tǒng)管理任務編寫腳本以及執(zhí)行這些任務庭敦。
Windows 實用的原生命令行網(wǎng)絡工具包括?ping,ipconfig薪缆,tracert秧廉,和?netstat。
可以使用?Rundll32?命令來實現(xiàn)許多有用的 Windows 任務?拣帽。
通過 Cygwin 的包管理器來安裝額外的 Unix 程序疼电。
使用?mintty?作為你的命令行窗口。
要訪問 Windows 剪貼板减拭,可以通過?/dev/clipboard蔽豺。
運行?cygstart?以通過默認程序打開一個文件。
要訪問 Windows 注冊表拧粪,可以使用?regtool修陡。
注意 Windows 驅(qū)動器路徑?C:\?在 Cygwin 中用?/cygdrive/c?代表沧侥,而 Cygwin 的?/?代表 Windows 中的?C:\cygwin。要轉(zhuǎn)換 Cygwin 和 Windows 風格的路徑可以用?cygpath濒析。這在需要調(diào)用 Windows 程序的腳本里很有用正什。
學會使用?wmic,你就可以從命令行執(zhí)行大多數(shù) Windows 系統(tǒng)管理任務号杏,并編成腳本婴氮。
要在 Windows 下獲得 Unix 的界面和體驗,另一個辦法是使用?Cash盾致。需要注意的是主经,這個環(huán)境支持的 Unix 命令和命令行參數(shù)非常少。
要在 Windows 上獲取 GNU 開發(fā)者工具(比如 GCC)的另一個辦法是使用?MinGW?以及它的?MSYS?軟件包庭惜,該軟件包提供了 bash罩驻、gawk、make护赊、grep 等工具惠遏。然而 MSYS 提供的功能沒有 Cygwin 完善。MinGW 在創(chuàng)建 Unix 工具的 Windows 原生移植方面非常有用骏啰。
awesome-shell:一份精心組織的命令行工具及資源的列表节吮。
awesome-osx-command-line:一份針對 OS X 命令行的更深入的指南。
Strict mode:為了編寫更好的腳本文件判耕。
shellcheck:一個靜態(tài) shell 腳本分析工具透绩,本質(zhì)上是 bash/sh/zsh 的 lint。
Filenames and Pathnames in Shell:有關(guān)如何在 shell 腳本里正確處理文件名的細枝末節(jié)壁熄。
Data Science at the Command Line:用于數(shù)據(jù)科學的一些命令和工具帚豪,摘自同名書籍。
除去特別小的工作草丧,你編寫的代碼應當方便他人閱讀狸臣。能力往往伴隨著責任,你?有能力?在 Bash 中玩一些奇技淫巧并不意味著你應該去做昌执!;)