命令行的艺术
轉(zhuǎn)自:Github
https://github.com/jlevy/the-art-of-command-line/blob/master/README-zh.md
熟練使用命令行是一種常常被忽視,或被認(rèn)為難以掌握的技能,但實(shí)際上,它會(huì)提高你作為工程師的靈活性以及生產(chǎn)力。本文是一份我在 Linux 上工作時(shí),發(fā)現(xiàn)的一些命令行使用技巧的摘要。有些技巧非常基礎(chǔ),而另一些則相當(dāng)復(fù)雜,甚至晦澀難懂。這篇文章并不長(zhǎng),但當(dāng)你能夠熟練掌握這里列出的所有技巧時(shí),你就學(xué)會(huì)了很多關(guān)于命令行的東西了。
這篇文章是許多作者和譯者共同的成果。這里的部分內(nèi)容?首次?出現(xiàn)?于 Quora, 但已經(jīng)遷移到了 Github,并由眾多高手做出了許多改進(jìn)。如果你在本文中發(fā)現(xiàn)了錯(cuò)誤或者存在可以改善的地方,請(qǐng)貢獻(xiàn)你的一份力量。
前言
涵蓋范圍:
這篇文章不僅能幫助剛接觸命令行的新手,而且對(duì)具有經(jīng)驗(yàn)的人也大有裨益。本文致力于做到覆蓋面廣(涉及所有重要的內(nèi)容),具體(給出具體的最常用的例子),以及簡(jiǎn)潔(避免冗余的內(nèi)容,或是可以在其他地方輕松查到的細(xì)枝末節(jié))。在特定應(yīng)用場(chǎng)景下,本文的內(nèi)容屬于基本功或者能幫助您節(jié)約大量的時(shí)間。
本文主要為 Linux 所寫,但在僅限 OS X 系統(tǒng)章節(jié)和僅限 Windows 系統(tǒng)章節(jié)中也包含有對(duì)應(yīng)操作系統(tǒng)的內(nèi)容。除去這兩個(gè)章節(jié)外,其它的內(nèi)容大部分均可在其他類 Unix 系統(tǒng)或 OS X,甚至 Cygwin 中得到應(yīng)用。
本文主要關(guān)注于交互式 Bash,但也有很多技巧可以應(yīng)用于其他 shell 和 Bash 腳本當(dāng)中。
除去“標(biāo)準(zhǔn)的”Unix 命令,本文還包括了一些依賴于特定軟件包的命令(前提是它們具有足夠的價(jià)值)。
注意事項(xiàng):
為了能在一頁(yè)內(nèi)展示盡量多的東西,一些具體的信息可以在引用的頁(yè)面中找到。我們相信機(jī)智的你知道如何使用 Google或者其他搜索引擎來(lái)查閱到更多的詳細(xì)信息。文中部分命令需要您使用?apt-get,yum,dnf,pacman,?pip?或?brew(以及其它合適的包管理器)來(lái)安裝依賴的程序。
遇到問(wèn)題的話,請(qǐng)嘗試使用 Explainshell去獲取相關(guān)命令、參數(shù)、管道等內(nèi)容的解釋。
基礎(chǔ)
學(xué)習(xí) Bash 的基礎(chǔ)知識(shí)。具體地,在命令行中輸入?man bash?并至少全文瀏覽一遍; 它理解起來(lái)很簡(jiǎn)單并且不冗長(zhǎng)。其他的 shell 可能很好用,但 Bash 的功能已經(jīng)足夠強(qiáng)大并且到幾乎總是可用的( 如果你只學(xué)習(xí) zsh,fish 或其他的 shell 的話,在你自己的設(shè)備上會(huì)顯得很方便,但過(guò)度依賴這些功能會(huì)給您帶來(lái)不便,例如當(dāng)你需要在服務(wù)器上工作時(shí))。
熟悉至少一個(gè)基于文本的編輯器。通常而言 Vim (vi) 會(huì)是你最好的選擇,畢竟在終端中編輯文本時(shí) Vim 是最好用的工具(甚至大部分情況下 Vim 要比 Emacs、大型 IDE 或是炫酷的編輯器更好用)。
學(xué)會(huì)如何使用?man?命令去閱讀文檔。學(xué)會(huì)使用?apropos?去查找文檔。知道有些命令并不對(duì)應(yīng)可執(zhí)行文件,而是在 Bash 內(nèi)置好的,此時(shí)可以使用?help?和?help -d?命令獲取幫助信息。你可以用?type 命令?來(lái)判斷這個(gè)命令到底是可執(zhí)行文件、shell 內(nèi)置命令還是別名。
學(xué)會(huì)使用?>?和?<?來(lái)重定向輸出和輸入,學(xué)會(huì)使用?|?來(lái)重定向管道。明白?>?會(huì)覆蓋了輸出文件而?>>?是在文件末添加。了解標(biāo)準(zhǔn)輸出 stdout 和標(biāo)準(zhǔn)錯(cuò)誤 stderr。
學(xué)會(huì)使用通配符?*?(或許再算上???和?[...]) 和引用以及引用中?'?和?"?的區(qū)別(后文中有一些具體的例子)。
熟悉 Bash 中的任務(wù)管理工具:&,ctrl-z,ctrl-c,jobs,fg,bg,kill等。
學(xué)會(huì)使用?ssh?進(jìn)行遠(yuǎn)程命令行登錄,最好知道如何使用?ssh-agent,ssh-add等命令來(lái)實(shí)現(xiàn)基礎(chǔ)的無(wú)密碼認(rèn)證登錄。
學(xué)會(huì)基本的文件管理工具: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)的管理,學(xué)習(xí)?df,mount,fdisk,mkfs,lsblk。知道 inode 是什么(與?ls -i?和?df -i?等命令相關(guān))。
學(xué)習(xí)基本的網(wǎng)絡(luò)管理工具:ip?或?ifconfig,dig。
學(xué)習(xí)并使用一種版本控制管理系統(tǒng),例如?git。
熟悉正則表達(dá)式,學(xué)會(huì)使用?grep/egrep,它們的參數(shù)中?-i,-o,-v,-A,-B?和?-C?這些是很常用并值得認(rèn)真學(xué)習(xí)的。
學(xué)會(huì)使用?apt-get,yum,dnf?或?pacman?(具體使用哪個(gè)取決于你使用的 Linux 發(fā)行版)來(lái)查找和安裝軟件包。并確保你的環(huán)境中有?pip?來(lái)安裝基于 Python 的命令行工具 (接下來(lái)提到的部分程序使用?pip?來(lái)安裝會(huì)很方便)。
日常使用
在 Bash 中,可以通過(guò)按?Tab?鍵實(shí)現(xiàn)自動(dòng)補(bǔ)全參數(shù),使用?ctrl-r?搜索命令行歷史記錄(按下按鍵之后,輸入關(guān)鍵字便可以搜索,重復(fù)按下?ctrl-r?會(huì)向后查找匹配項(xiàng),按下?Enter?鍵會(huì)執(zhí)行當(dāng)前匹配的命令,而按下右方向鍵會(huì)將匹配項(xiàng)放入當(dāng)前行中,不會(huì)直接執(zhí)行,以便做出修改)。
在 Bash 中,可以按下?ctrl-w?刪除你鍵入的最后一個(gè)單詞,ctrl-u?可以刪除行內(nèi)光標(biāo)所在位置之前的內(nèi)容,alt-b?和?alt-f?可以以單詞為單位移動(dòng)光標(biāo),ctrl-a?可以將光標(biāo)移至行首,ctrl-e?可以將光標(biāo)移至行尾,ctrl-k?可以刪除光標(biāo)至行尾的所有內(nèi)容,ctrl-l?可以清屏。鍵入?man readline?可以查看 Bash 中的默認(rèn)快捷鍵。內(nèi)容有很多,例如?alt-.?循環(huán)地移向前一個(gè)參數(shù),而?alt-* 可以展開通配符。
你喜歡的話,可以執(zhí)行?set -o vi?來(lái)使用 vi 風(fēng)格的快捷鍵,而執(zhí)行?set -o emacs?可以把它改回來(lái)。
為了便于編輯長(zhǎng)命令,在設(shè)置你的默認(rèn)編輯器后(例如?export EDITOR=vim),ctrl-x?ctrl-e?會(huì)打開一個(gè)編輯器來(lái)編輯當(dāng)前輸入的命令。在 vi 風(fēng)格下快捷鍵則是?escape-v。
鍵入?history?查看命令行歷史記錄,再用?!n(n?是命令編號(hào))就可以再次執(zhí)行。其中有許多縮寫,最有用的大概就是?!$, 它用于指代上次鍵入的參數(shù),而?!!?可以指代上次鍵入的命令了(參考 man 頁(yè)面中的“HISTORY EXPANSION”)。不過(guò)這些功能,你也可以通過(guò)快捷鍵?ctrl-r?和?alt-.?來(lái)實(shí)現(xiàn)。
cd?命令可以切換工作路徑,輸入?cd ~可以進(jìn)入 home 目錄。要訪問(wèn)你的 home 目錄中的文件,可以使用前綴?~(例如?~/.bashrc)。在?sh?腳本里則用環(huán)境變量?$HOME?指代 home 目錄的路徑。
回到前一個(gè)工作路徑:cd -。
如果你輸入命令的時(shí)候中途改了主意,按下?alt-#?在行首添加?#?把它當(dāng)做注釋再按下回車執(zhí)行(或者依次按下?ctrl-a,?#,?enter)。這樣做的話,之后借助命令行歷史記錄,你可以很方便恢復(fù)你剛才輸入到一半的命令。
使用?xargs?( 或?parallel)。他們非常給力。注意到你可以控制每行參數(shù)個(gè)數(shù)(-L)和最大并行數(shù)(-P)。如果你不確定它們是否會(huì)按你想的那樣工作,先使用?xargs echo?查看一下。此外,使用?-I{}?會(huì)很方便。例如:
pstree -p?以一種優(yōu)雅的方式展示進(jìn)程樹。
使用?pgrep?和?pkill?根據(jù)名字查找進(jìn)程或發(fā)送信號(hào)(-f?參數(shù)通常有用)。
了解你可以發(fā)往進(jìn)程的信號(hào)的種類。比如,使用?kill -STOP [pid]?停止一個(gè)進(jìn)程。使用?man 7 signal?查看詳細(xì)列表。
使用?nohup?或?disown?使一個(gè)后臺(tái)進(jìn)程持續(xù)運(yùn)行。
使用?netstat -lntp?或?ss -plat?檢查哪些進(jìn)程在監(jiān)聽端口(默認(rèn)是檢查 TCP 端口; 添加參數(shù)?-u?則檢查 UDP 端口)或者?lsof -iTCP -sTCP:LISTEN -P -n?(這也可以在 OS X 上運(yùn)行)。
lsof?來(lái)查看開啟的套接字和文件。
使用?uptime?或?w?來(lái)查看系統(tǒng)已經(jīng)運(yùn)行多長(zhǎng)時(shí)間。
使用?alias?來(lái)創(chuàng)建常用命令的快捷形式。例如:alias ll='ls -latr'?創(chuàng)建了一個(gè)新的命令別名?ll。
可以把別名、shell 選項(xiàng)和常用函數(shù)保存在?~/.bashrc,具體看下這篇文章。這樣做的話你就可以在所有 shell 會(huì)話中使用你的設(shè)定。
把環(huán)境變量的設(shè)定以及登陸時(shí)要執(zhí)行的命令保存在?~/.bash_profile。而對(duì)于從圖形界面啟動(dòng)的 shell 和?cron?啟動(dòng)的 shell,則需要單獨(dú)配置文件。
要想在幾臺(tái)電腦中同步你的配置文件(例如?.bashrc?和?.bash_profile),可以借助 Git。
當(dāng)變量和文件名中包含空格的時(shí)候要格外小心。Bash 變量要用引號(hào)括起來(lái),比如?"$FOO"。盡量使用?-0?或?-print0?選項(xiàng)以便用 NULL 來(lái)分隔文件名,例如?locate -0 pattern | xargs -0 ls -al或?find / -print0 -type d | xargs -0 ls -al。如果 for 循環(huán)中循環(huán)訪問(wèn)的文件名含有空字符(空格、tab 等字符),只需用?IFS=$' '?把內(nèi)部字段分隔符設(shè)為換行符。
在 Bash 腳本中,使用?set -x?去調(diào)試輸出(或者使用它的變體?set -v,它會(huì)記錄原始輸入,包括多余的參數(shù)和注釋)。盡可能地使用嚴(yán)格模式:使用?set -e令腳本在發(fā)生錯(cuò)誤時(shí)退出而不是繼續(xù)運(yùn)行;使用?set -u?來(lái)檢查是否使用了未賦值的變量;試試?set -o pipefail,它可以監(jiān)測(cè)管道中的錯(cuò)誤。當(dāng)牽扯到很多腳本時(shí),使用?trap?來(lái)檢測(cè) ERR 和 EXIT。一個(gè)好的習(xí)慣是在腳本文件開頭這樣寫,這會(huì)使它能夠檢測(cè)一些錯(cuò)誤,并在錯(cuò)誤發(fā)生時(shí)中斷程序并輸出信息:
在 Bash 腳本中,子 shell(使用括號(hào)?(...))是一種組織參數(shù)的便捷方式。一個(gè)常見的例子是臨時(shí)地移動(dòng)工作路徑,代碼如下:
在 Bash 中,變量有許多的擴(kuò)展方式。${name:?error message}?用于檢查變量是否存在。此外,當(dāng) Bash 腳本只需要一個(gè)參數(shù)時(shí),可以使用這樣的代碼?input_file=${1:?usage: $0 input_file}。在變量為空時(shí)使用默認(rèn)值:${name:-default}。如果你要在之前的例子中再加一個(gè)(可選的)參數(shù),可以使用類似這樣的代碼?output_file=${2:-logfile},如果省略了 2,它的值就為空,于是 `output_file` 就會(huì)被設(shè)為 `logfile`。數(shù)學(xué)表達(dá)式:`i=(( (i + 1) % 5 ))。序列:{1..10}。截?cái)嘧址?#xff1a;{var%suffix}` 和 `{var#prefix}。例如,假設(shè)var=foo.pdf,那么echo ${var%.pdf}.txt將輸出foo.txt`。
使用括號(hào)擴(kuò)展({...})來(lái)減少輸入相似文本,并自動(dòng)化文本組合。這在某些情況下會(huì)很有用,例如?mv foo.{txt,pdf} some-dir(同時(shí)移動(dòng)兩個(gè)文件),cp somefile{,.bak}(會(huì)被擴(kuò)展成?cp somefile somefile.bak)或者?mkdir -p test-{a,b,c}/subtest-{1,2,3}(會(huì)被擴(kuò)展成所有可能的組合,并創(chuàng)建一個(gè)目錄樹)。
通過(guò)使用?<(some command)?可以將輸出視為文件。例如,對(duì)比本地文件?/etc/hosts?和一個(gè)遠(yuǎn)程文件:
編寫腳本時(shí),你可能會(huì)想要把代碼都放在大括號(hào)里。缺少右括號(hào)的話,代碼就會(huì)因?yàn)檎Z(yǔ)法錯(cuò)誤而無(wú)法執(zhí)行。如果你的腳本是要放在網(wǎng)上分享供他人使用的,這樣的寫法就體現(xiàn)出它的好處了,因?yàn)檫@樣可以防止下載不完全代碼被執(zhí)行。
了解 Bash 中的“here documents”,例如?cat <<EOF ...。
在 Bash 中,同時(shí)重定向標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤:some-command >logfile 2>&1?或者?some-command &>logfile。通常,為了保證命令不會(huì)在標(biāo)準(zhǔn)輸入里殘留一個(gè)未關(guān)閉的文件句柄捆綁在你當(dāng)前所在的終端上,在命令后添加?</dev/null?是一個(gè)好習(xí)慣。
使用?man ascii?查看具有十六進(jìn)制和十進(jìn)制值的ASCII表。man unicode,man utf-8,以及?man latin1?有助于你去了解通用的編碼信息。
使用?screen?或?tmux?來(lái)使用多份屏幕,當(dāng)你在使用 ssh 時(shí)(保存 session 信息)將尤為有用。而?byobu?可以為它們提供更多的信息和易用的管理工具。另一個(gè)輕量級(jí)的 session 持久化解決方案是?dtach。
ssh 中,了解如何使用?-L?或?-D(偶爾需要用?-R)開啟隧道是非常有用的,比如當(dāng)你需要從一臺(tái)遠(yuǎn)程服務(wù)器上訪問(wèn) web 頁(yè)面。
對(duì) ssh 設(shè)置做一些小優(yōu)化可能是很有用的,例如這個(gè)?~/.ssh/config?文件包含了防止特定網(wǎng)絡(luò)環(huán)境下連接斷開、壓縮數(shù)據(jù)、多通道等選項(xiàng):
一些其他的關(guān)于 ssh 的選項(xiàng)是與安全相關(guān)的,應(yīng)當(dāng)小心翼翼的使用。例如你應(yīng)當(dāng)只能在可信任的網(wǎng)絡(luò)中啟用?StrictHostKeyChecking=no,ForwardAgent=yes。
考慮使用?mosh?作為 ssh 的替代品,它使用 UDP 協(xié)議。它可以避免連接被中斷并且對(duì)帶寬需求更小,但它需要在服務(wù)端做相應(yīng)的配置。
獲取八進(jìn)制形式的文件訪問(wèn)權(quán)限(修改系統(tǒng)設(shè)置時(shí)通常需要,但?ls?的功能不那么好用并且通常會(huì)搞砸),可以使用類似如下的代碼:
使用?percol?或者?fzf?可以交互式地從另一個(gè)命令輸出中選取值。
使用?fpp(PathPicker)可以與基于另一個(gè)命令(例如?git)輸出的文件交互。
將 web 服務(wù)器上當(dāng)前目錄下所有的文件(以及子目錄)暴露給你所處網(wǎng)絡(luò)的所有用戶,使用:?python -m SimpleHTTPServer 7777?(使用端口 7777 和 Python 2)或python -m http.server 7777?(使用端口 7777 和 Python 3)。
以其他用戶的身份執(zhí)行命令,使用?sudo。默認(rèn)以 root 用戶的身份執(zhí)行;使用?-u?來(lái)指定其他用戶。使用?-i?來(lái)以該用戶登錄(需要輸入_你自己的_密碼)。
將 shell 切換為其他用戶,使用?su username?或者?sudo - username。加入?-?會(huì)使得切換后的環(huán)境與使用該用戶登錄后的環(huán)境相同。省略用戶名則默認(rèn)為 root。切換到哪個(gè)用戶,就需要輸入_哪個(gè)用戶的_密碼。
了解命令行的 128K 限制。使用通配符匹配大量文件名時(shí),常會(huì)遇到“Argument list too long”的錯(cuò)誤信息。(這種情況下?lián)Q用?find?或?xargs?通常可以解決。)
當(dāng)你需要一個(gè)基本的計(jì)算器時(shí),可以使用?python?解釋器(當(dāng)然你要用 python 的時(shí)候也是這樣)。例如:
文件及數(shù)據(jù)處理
在當(dāng)前目錄下通過(guò)文件名查找一個(gè)文件,使用類似于這樣的命令:find . -iname '*something*'。在所有路徑下通過(guò)文件名查找文件,使用?locate something(但注意到?updatedb?可能沒(méi)有對(duì)最近新建的文件建立索引,所以你可能無(wú)法定位到這些未被索引的文件)。
使用?ag?在源代碼或數(shù)據(jù)文件里檢索(grep -r?同樣可以做到,但相比之下?ag?更加先進(jìn))。
將 HTML 轉(zhuǎn)為文本:lynx -dump -stdin。
Markdown,HTML,以及所有文檔格式之間的轉(zhuǎn)換,試試?pandoc。
當(dāng)你要處理棘手的 XML 時(shí)候,xmlstarlet?算是上古時(shí)代流傳下來(lái)的神器。
使用?jq?處理 JSON。
使用?shyaml?處理 YAML。
要處理 Excel 或 CSV 文件的話,csvkit?提供了?in2csv,csvcut,csvjoin,csvgrep?等方便易用的工具。
當(dāng)你要處理 Amazon S3 相關(guān)的工作的時(shí)候,s3cmd?是一個(gè)很方便的工具而?s4cmd?的效率更高。Amazon 官方提供的?aws?以及?saws?是其他 AWS 相關(guān)工作的基礎(chǔ),值得學(xué)習(xí)。
了解如何使用?sort?和?uniq,包括 uniq 的?-u?參數(shù)和?-d?參數(shù),具體內(nèi)容在后文單行腳本節(jié)中。另外可以了解一下?comm。
了解如何使用?cut,paste?和?join?來(lái)更改文件。很多人都會(huì)使用?cut,但遺忘了?join。
了解如何運(yùn)用?wc?去計(jì)算新行數(shù)(-l),字符數(shù)(-m),單詞數(shù)(-w)以及字節(jié)數(shù)(-c)。
了解如何使用?tee?將標(biāo)準(zhǔn)輸入復(fù)制到文件甚至標(biāo)準(zhǔn)輸出,例如?ls -al | tee file.txt。
要進(jìn)行一些復(fù)雜的計(jì)算,比如分組、逆序和一些其他的統(tǒng)計(jì)分析,可以考慮使用?datamash。
注意到語(yǔ)言設(shè)置(中文或英文等)對(duì)許多命令行工具有一些微妙的影響,比如排序的順序和性能。大多數(shù) Linux 的安裝過(guò)程會(huì)將?LANG?或其他有關(guān)的變量設(shè)置為符合本地的設(shè)置。要意識(shí)到當(dāng)你改變語(yǔ)言設(shè)置時(shí),排序的結(jié)果可能會(huì)改變。明白國(guó)際化可能會(huì)使 sort 或其他命令運(yùn)行效率下降許多倍。某些情況下(例如集合運(yùn)算)你可以放心的使用?export LC_ALL=C?來(lái)忽略掉國(guó)際化并按照字節(jié)來(lái)判斷順序。
你可以單獨(dú)指定某一條命令的環(huán)境,只需在調(diào)用時(shí)把環(huán)境變量設(shè)定放在命令的前面,例如?TZ=Pacific/Fiji date?可以獲取斐濟(jì)的時(shí)間。
了解如何使用?awk?和?sed?來(lái)進(jìn)行簡(jiǎn)單的數(shù)據(jù)處理。參閱 One-liners 獲取示例。
替換一個(gè)或多個(gè)文件中出現(xiàn)的字符串:
使用?repren?來(lái)批量重命名文件,或是在多個(gè)文件中搜索替換內(nèi)容。(有些時(shí)候?rename?命令也可以批量重命名,但要注意,它在不同 Linux 發(fā)行版中的功能并不完全一樣。)
根據(jù) man 頁(yè)面的描述,rsync?是一個(gè)快速且非常靈活的文件復(fù)制工具。它聞名于設(shè)備之間的文件同步,但其實(shí)它在本地情況下也同樣有用。在安全設(shè)置允許下,用?rsync?代替?scp?可以實(shí)現(xiàn)文件續(xù)傳,而不用重新從頭開始。它同時(shí)也是刪除大量文件的最快方法之一:
若要在復(fù)制文件時(shí)獲取當(dāng)前進(jìn)度,可使用?pv,pycp,progress,rsync --progress。若所執(zhí)行的復(fù)制為block塊拷貝,可以使用?dd status=progress。
使用?shuf?可以以行為單位來(lái)打亂文件的內(nèi)容或從一個(gè)文件中隨機(jī)選取多行。
了解?sort?的參數(shù)。顯示數(shù)字時(shí),使用?-n?或者?-h?來(lái)顯示更易讀的數(shù)(例如?du -h?的輸出)。明白排序時(shí)關(guān)鍵字的工作原理(-t?和?-k)。例如,注意到你需要?-k1,1?來(lái)僅按第一個(gè)域來(lái)排序,而?-k1?意味著按整行排序。穩(wěn)定排序(sort -s)在某些情況下很有用。例如,以第二個(gè)域?yàn)橹麝P(guān)鍵字,第一個(gè)域?yàn)榇侮P(guān)鍵字進(jìn)行排序,你可以使用?sort -k1,1 | sort -s -k2,2。
如果你想在 Bash 命令行中寫 tab 制表符,按下?ctrl-v?[Tab]?或鍵入?$' '(后者可能更好,因?yàn)槟憧梢詮?fù)制粘貼它)。
標(biāo)準(zhǔn)的源代碼對(duì)比及合并工具是?diff和?patch。使用?diffstat?查看變更總覽數(shù)據(jù)。注意到?diff -r?對(duì)整個(gè)文件夾有效。使用?diff -r tree1 tree2 | diffstat?查看變更的統(tǒng)計(jì)數(shù)據(jù)。vimdiff?用于比對(duì)并編輯文件。
對(duì)于二進(jìn)制文件,使用?hd,hexdump或者?xxd?使其以十六進(jìn)制顯示,使用?bvi,hexedit?或者?biew?來(lái)進(jìn)行二進(jìn)制編輯。
同樣對(duì)于二進(jìn)制文件,strings(包括?grep?等工具)可以幫助在二進(jìn)制文件中查找特定比特。
制作二進(jìn)制差分文件(Delta 壓縮),使用?xdelta3。
使用?iconv?更改文本編碼。需要更高級(jí)的功能,可以使用?uconv,它支持一些高級(jí)的 Unicode 功能。例如,這條命令移除了所有重音符號(hào):
拆分文件可以使用?split(按大小拆分)和?csplit(按模式拆分)。
操作日期和時(shí)間表達(dá)式,可以用?dateutils?中的?dateadd、datediff、strptime?等工具。
使用?zless、zmore、zcat?和?zgrep對(duì)壓縮過(guò)的文件進(jìn)行操作。
文件屬性可以通過(guò)?chattr?進(jìn)行設(shè)置,它比文件權(quán)限更加底層。例如,為了保護(hù)文件不被意外刪除,可以使用不可修改標(biāo)記:sudo chattr +i /critical/directory/or/file
使用?getfacl?和?setfacl?以保存和恢復(fù)文件權(quán)限。例如:
為了高效地創(chuàng)建空文件,請(qǐng)使用?truncate(創(chuàng)建稀疏文件),fallocate(用于 ext4,xfs,btrf 和 ocfs2 文件系統(tǒng)),xfs_mkfile(適用于幾乎所有的文件系統(tǒng),包含在 xfsprogs 包中),mkfile(用于類 Unix 操作系統(tǒng),比如 Solaris 和 Mac OS)。
系統(tǒng)調(diào)試
curl?和?curl -I?可以被輕松地應(yīng)用于 web 調(diào)試中,它們的好兄弟?wget?也是如此,或者也可以試試更潮的?httpie。
獲取 CPU 和硬盤的使用狀態(tài),通常使用使用?top(htop?更佳),iostat?和?iotop。而?iostat -mxz 15?可以讓你獲悉 CPU 和每個(gè)硬盤分區(qū)的基本信息和性能表現(xiàn)。
使用?netstat?和?ss?查看網(wǎng)絡(luò)連接的細(xì)節(jié)。
dstat?在你想要對(duì)系統(tǒng)的現(xiàn)狀有一個(gè)粗略的認(rèn)識(shí)時(shí)是非常有用的。然而若要對(duì)系統(tǒng)有一個(gè)深度的總體認(rèn)識(shí),使用?glances,它會(huì)在一個(gè)終端窗口中向你提供一些系統(tǒng)級(jí)的數(shù)據(jù)。
若要了解內(nèi)存狀態(tài),運(yùn)行并理解?free和?vmstat?的輸出。值得留意的是“cached”的值,它指的是 Linux 內(nèi)核用來(lái)作為文件緩存的內(nèi)存大小,而與空閑內(nèi)存無(wú)關(guān)。
Java 系統(tǒng)調(diào)試則是一件截然不同的事,一個(gè)可以用于 Oracle 的 JVM 或其他 JVM 上的調(diào)試的技巧是你可以運(yùn)行?kill -3 <pid>?同時(shí)一個(gè)完整的棧軌跡和堆概述(包括 GC 的細(xì)節(jié))會(huì)被保存到標(biāo)準(zhǔn)錯(cuò)誤或是日志文件。JDK 中的?jps,jstat,jstack,jmap?很有用。SJK tools 更高級(jí)。
使用?mtr?去跟蹤路由,用于確定網(wǎng)絡(luò)問(wèn)題。
用?ncdu?來(lái)查看磁盤使用情況,它比尋常的命令,如?du -sh *,更節(jié)省時(shí)間。
查找正在使用帶寬的套接字連接或進(jìn)程,使用?iftop?或?nethogs。
ab?工具(Apache 中自帶)可以簡(jiǎn)單粗暴地檢查 web 服務(wù)器的性能。對(duì)于更復(fù)雜的負(fù)載測(cè)試,使用?siege。
wireshark,tshark?和?ngrep?可用于復(fù)雜的網(wǎng)絡(luò)調(diào)試。
了解?strace?和?ltrace。這倆工具在你的程序運(yùn)行失敗、掛起甚至崩潰,而你卻不知道為什么或你想對(duì)性能有個(gè)總體的認(rèn)識(shí)的時(shí)候是非常有用的。注意 profile 參數(shù)(-c)和附加到一個(gè)運(yùn)行的進(jìn)程參數(shù) (-p)。
了解使用?ldd?來(lái)檢查共享庫(kù)。但是永遠(yuǎn)不要在不信任的文件上運(yùn)行。
了解如何運(yùn)用?gdb?連接到一個(gè)運(yùn)行著的進(jìn)程并獲取它的堆棧軌跡。
學(xué)會(huì)使用?/proc。它在調(diào)試正在出現(xiàn)的問(wèn)題的時(shí)候有時(shí)會(huì)效果驚人。比如:/proc/cpuinfo,/proc/meminfo,/proc/cmdline,/proc/xxx/cwd,/proc/xxx/exe,/proc/xxx/fd/,/proc/xxx/smaps(這里的?xxx?表示進(jìn)程的 id 或 pid)。
當(dāng)調(diào)試一些之前出現(xiàn)的問(wèn)題的時(shí)候,sar?非常有用。它展示了 cpu、內(nèi)存以及網(wǎng)絡(luò)等的歷史數(shù)據(jù)。
關(guān)于更深層次的系統(tǒng)分析以及性能分析,看看?stap(SystemTap),perf,以及sysdig。
查看你當(dāng)前使用的系統(tǒng),使用?uname,uname -a(Unix/kernel 信息)或者?lsb_release -a(Linux 發(fā)行版信息)。
無(wú)論什么東西工作得很歡樂(lè)(可能是硬件或驅(qū)動(dòng)問(wèn)題)時(shí)可以試試?dmesg。
如果你刪除了一個(gè)文件,但通過(guò)?du?發(fā)現(xiàn)沒(méi)有釋放預(yù)期的磁盤空間,請(qǐng)檢查文件是否被進(jìn)程占用:?lsof | grep deleted | grep "filename-of-my-big-file"
單行腳本
一些命令組合的例子:
當(dāng)你需要對(duì)文本文件做集合交、并、差運(yùn)算時(shí),sort?和?uniq?會(huì)是你的好幫手。具體例子請(qǐng)參照代碼后面的,此處假設(shè)?a?與?b?是兩內(nèi)容不同的文件。這種方式效率很高,并且在小文件和上 G 的文件上都能運(yùn)用(注意盡管在?/tmp?在一個(gè)小的根分區(qū)上時(shí)你可能需要?-T?參數(shù),但是實(shí)際上?sort?并不被內(nèi)存大小約束),參閱前文中關(guān)于?LC_ALL?和?sort的?-u?參數(shù)的部分。
使用?grep . *(每行都會(huì)附上文件名)或者?head -100 *(每個(gè)文件有一個(gè)標(biāo)題)來(lái)閱讀檢查目錄下所有文件的內(nèi)容。這在檢查一個(gè)充滿配置文件的目錄(如?/sys、/proc、/etc)時(shí)特別好用。
計(jì)算文本文件第三列中所有數(shù)的和(可能比同等作用的 Python 代碼快三倍且代碼量少三倍):
如果你想在文件樹上查看大小/日期,這可能看起來(lái)像遞歸版的?ls -l?但比?ls -lR?更易于理解:
假設(shè)你有一個(gè)類似于 web 服務(wù)器日志文件的文本文件,并且一個(gè)確定的值只會(huì)出現(xiàn)在某些行上,假設(shè)一個(gè)?acct_id?參數(shù)在 URI 中。如果你想計(jì)算出每個(gè)?acct_id?值有多少次請(qǐng)求,使用如下代碼:
要持續(xù)監(jiān)測(cè)文件改動(dòng),可以使用?watch,例如檢查某個(gè)文件夾中文件的改變,可以用?watch -d -n 2 'ls -rtlh | tail';或者在排查 WiFi 設(shè)置故障時(shí)要監(jiān)測(cè)網(wǎng)絡(luò)設(shè)置的更改,可以用?watch -d -n 2 ifconfig。
運(yùn)行這個(gè)函數(shù)從這篇文檔中隨機(jī)獲取一條技巧(解析 Markdown 文件并抽取項(xiàng)目):
冷門但有用
expr:計(jì)算表達(dá)式或正則匹配
m4:簡(jiǎn)單的宏處理器
yes:多次打印字符串
cal:漂亮的日歷
env:執(zhí)行一個(gè)命令(腳本文件中很有用)
printenv:打印環(huán)境變量(調(diào)試時(shí)或在寫腳本文件時(shí)很有用)
look:查找以特定字符串開頭的單詞或行
cut,paste?和?join:數(shù)據(jù)修改
fmt:格式化文本段落
pr:將文本格式化成頁(yè)/列形式
fold:包裹文本中的幾行
column:將文本格式化成多個(gè)對(duì)齊、定寬的列或表格
expand?和?unexpand:制表符與空格之間轉(zhuǎn)換
nl:添加行號(hào)
seq:打印數(shù)字
bc:計(jì)算器
factor:分解因數(shù)
gpg:加密并簽名文件
toe:terminfo 入口列表
nc:網(wǎng)絡(luò)調(diào)試及數(shù)據(jù)傳輸
socat:套接字代理,與?netcat?類似
slurm:網(wǎng)絡(luò)流量可視化
dd:文件或設(shè)備間傳輸數(shù)據(jù)
file:確定文件類型
tree:以樹的形式顯示路徑和文件,類似于遞歸的?ls
stat:文件信息
time:執(zhí)行命令,并計(jì)算執(zhí)行時(shí)間
timeout:在指定時(shí)長(zhǎng)范圍內(nèi)執(zhí)行命令,并在規(guī)定時(shí)間結(jié)束后停止進(jìn)程
lockfile:使文件只能通過(guò)?rm -f?移除
logrotate:切換、壓縮以及發(fā)送日志文件
watch:重復(fù)運(yùn)行同一個(gè)命令,展示結(jié)果并/或高亮有更改的部分
when-changed:當(dāng)檢測(cè)到文件更改時(shí)執(zhí)行指定命令。參閱?inotifywait?和?entr。
tac:反向輸出文件
shuf:文件中隨機(jī)選取幾行
comm:一行一行的比較排序過(guò)的文件
strings:從二進(jìn)制文件中抽取文本
tr:轉(zhuǎn)換字母
iconv?或?uconv:文本編碼轉(zhuǎn)換
split?和?csplit:分割文件
sponge:在寫入前讀取所有輸入,在讀取文件后再向同一文件寫入時(shí)比較有用,例如?grep -v something some-file | sponge some-file
units:將一種計(jì)量單位轉(zhuǎn)換為另一種等效的計(jì)量單位(參閱?/usr/share/units/definitions.units)
apg:隨機(jī)生成密碼
xz:高比例的文件壓縮
ldd:動(dòng)態(tài)庫(kù)信息
nm:提取 obj 文件中的符號(hào)
ab?或?wrk:web 服務(wù)器性能分析
strace:調(diào)試系統(tǒng)調(diào)用
mtr:更好的網(wǎng)絡(luò)調(diào)試跟蹤工具
cssh:可視化的并發(fā) shell
rsync:通過(guò) ssh 或本地文件系統(tǒng)同步文件和文件夾
wireshark?和?tshark:抓包和網(wǎng)絡(luò)調(diào)試工具
ngrep:網(wǎng)絡(luò)層的 grep
host?和?dig:DNS 查找
lsof:列出當(dāng)前系統(tǒng)打開文件的工具以及查看端口信息
dstat:系統(tǒng)狀態(tài)查看
glances:高層次的多子系統(tǒng)總覽
iostat:硬盤使用狀態(tài)
mpstat:CPU 使用狀態(tài)
vmstat:內(nèi)存使用狀態(tài)
htop:top 的加強(qiáng)版
last:登入記錄
w:查看處于登錄狀態(tài)的用戶
id:用戶/組 ID 信息
sar:系統(tǒng)歷史數(shù)據(jù)
iftop?或?nethogs:套接字及進(jìn)程的網(wǎng)絡(luò)利用情況
ss:套接字?jǐn)?shù)據(jù)
dmesg:引導(dǎo)及系統(tǒng)錯(cuò)誤信息
sysctl:在內(nèi)核運(yùn)行時(shí)動(dòng)態(tài)地查看和修改內(nèi)核的運(yùn)行參數(shù)
hdparm:SATA/ATA 磁盤更改及性能分析
lsblk:列出塊設(shè)備信息:以樹形展示你的磁盤以及磁盤分區(qū)信息
lshw,lscpu,lspci,lsusb?和?dmidecode:查看硬件信息,包括 CPU、BIOS、RAID、顯卡、USB設(shè)備等
lsmod?和?modinfo:列出內(nèi)核模塊,并顯示其細(xì)節(jié)
fortune,ddate?和?sl:額,這主要取決于你是否認(rèn)為蒸汽火車和莫名其妙的名人名言是否“有用
僅限 OS X 系統(tǒng)
以下是僅限于?OS X 系統(tǒng)的技巧。
用?brew?(Homebrew)或者?port(MacPorts)進(jìn)行包管理。這些可以用來(lái)在 OS X 系統(tǒng)上安裝以上的大多數(shù)命令。
用?pbcopy?復(fù)制任何命令的輸出到桌面應(yīng)用,用?pbpaste?粘貼輸入。
若要在 OS X 終端中將 Option 鍵視為 alt 鍵(例如在上面介紹的?alt-b、alt-f?等命令中用到),打開 偏好設(shè)置 -> 描述文件 -> 鍵盤 并勾選“使用 Option 鍵作為 Meta 鍵”。
用?open?或者?open -a /Applications/Whatever.app?使用桌面應(yīng)用打開文件。
Spotlight:用?mdfind?搜索文件,用?mdls?列出元數(shù)據(jù)(例如照片的 EXIF 信息)。
注意 OS X 系統(tǒng)是基于 BSD UNIX 的,許多命令(例如?ps,ls,tail,awk,sed)都和 Linux 中有微妙的不同( Linux 很大程度上受到了 System V-style Unix 和 GNU 工具影響)。你可以通過(guò)標(biāo)題為 "BSD General Commands Manual" 的 man 頁(yè)面發(fā)現(xiàn)這些不同。在有些情況下 GNU 版本的命令也可能被安裝(例如?gawk?和?gsed?對(duì)應(yīng) GNU 中的 awk 和 sed )。如果要寫跨平臺(tái)的 Bash 腳本,避免使用這些命令(例如,考慮 Python 或者?perl?)或者經(jīng)過(guò)仔細(xì)的測(cè)試。
用?sw_vers?獲取 OS X 的版本信息。
僅限 Windows 系統(tǒng)
以下是僅限于?Windows 系統(tǒng)的技巧。
在 Winodws 下獲取 Unix 工具
可以安裝 Cygwin 允許你在 Microsoft Windows 中體驗(yàn) Unix shell 的威力。這樣的話,本文中介紹的大多數(shù)內(nèi)容都將適用。
在 Windows 10 上,你可以使用 Bash on Ubuntu on Windows,它提供了一個(gè)熟悉的 Bash 環(huán)境,包含了不少 Unix 命令行工具。好處是它允許 Linux 上編寫的程序在 Windows 上運(yùn)行,而另一方面,Windows 上編寫的程序卻無(wú)法在 Bash 命令行中運(yùn)行。
如果你在 Windows 上主要想用 GNU 開發(fā)者工具(例如 GCC),可以考慮 MinGW以及它的 MSYS 包,這個(gè)包提供了例如 bash,gawk,make 和 grep 的工具。MSYS 并不包含所有可以與 Cygwin 媲美的特性。當(dāng)制作 Unix 工具的原生 Windows 端口時(shí) MinGW 將特別地有用。
另一個(gè)在 Windows 下實(shí)現(xiàn)接近 Unix 環(huán)境外觀效果的選項(xiàng)是 Cash。注意在此環(huán)境下只有很少的 Unix 命令和命令行可用。
實(shí)用 Windows 命令行工具
可以使用?wmic?在命令行環(huán)境下給大部分 Windows 系統(tǒng)管理任務(wù)編寫腳本以及執(zhí)行這些任務(wù)。
Windows 實(shí)用的原生命令行網(wǎng)絡(luò)工具包括?ping,ipconfig,tracert,和?netstat。
可以使用?Rundll32?命令來(lái)實(shí)現(xiàn)許多有用的 Windows 任務(wù)?。
Cygwin 技巧
通過(guò) Cygwin 的包管理器來(lái)安裝額外的 Unix 程序。
使用?mintty?作為你的命令行窗口。
要訪問(wèn) Windows 剪貼板,可以通過(guò)?/dev/clipboard。
運(yùn)行?cygstart?以通過(guò)默認(rèn)程序打開一個(gè)文件。
要訪問(wèn) Windows 注冊(cè)表,可以使用?regtool。
注意 Windows 驅(qū)動(dòng)器路徑?C:?在 Cygwin 中用?/cygdrive/c?代表,而 Cygwin 的?/?代表 Windows 中的?C:cygwin。要轉(zhuǎn)換 Cygwin 和 Windows 風(fēng)格的路徑可以用?cygpath。這在需要調(diào)用 Windows 程序的腳本里很有用。
學(xué)會(huì)使用?wmic,你就可以從命令行執(zhí)行大多數(shù) Windows 系統(tǒng)管理任務(wù),并編成腳本。
要在 Windows 下獲得 Unix 的界面和體驗(yàn),另一個(gè)辦法是使用 Cash。需要注意的是,這個(gè)環(huán)境支持的 Unix 命令和命令行參數(shù)非常少。
要在 Windows 上獲取 GNU 開發(fā)者工具(比如 GCC)的另一個(gè)辦法是使用 MinGW 以及它的 MSYS 軟件包,該軟件包提供了 bash、gawk、make、grep 等工具。然而 MSYS 提供的功能沒(méi)有 Cygwin 完善。MinGW 在創(chuàng)建 Unix 工具的 Windows 原生移植方面非常有用。
更多資源
awesome-shell:一份精心組織的命令行工具及資源的列表。
awesome-osx-command-line:一份針對(duì) OS X 命令行的更深入的指南。
Strict mode:為了編寫更好的腳本文件。
shellcheck:一個(gè)靜態(tài) shell 腳本分析工具,本質(zhì)上是 bash/sh/zsh 的 lint。
Filenames and Pathnames in Shell:有關(guān)如何在 shell 腳本里正確處理文件名的細(xì)枝末節(jié)。
Data Science at the Command Line:用于數(shù)據(jù)科學(xué)的一些命令和工具,摘自同名書籍。
免責(zé)聲明
除去特別小的工作,你編寫的代碼應(yīng)當(dāng)方便他人閱讀。能力往往伴隨著責(zé)任,你?有能力在 Bash 中玩一些奇技淫巧并不意味著你應(yīng)該去做!;)
授權(quán)條款
本文使用授權(quán)協(xié)議 Creative Commons Attribution-ShareAlike 4.0 International License
總結(jié)
- 上一篇: 《中餐厅》弹幕数据分析,我不要你觉得,我
- 下一篇: 周董新歌搞崩QQ,透过20W评论,看看歌