命令行:增強版
我不確定有多少 Web 開發者能完全避免使用命令行。就我來說,我從 1997 年上大學就開始使用命令行了,那時的 l33t-hacker 讓我著迷,同時我也覺得它很難掌握。
過去這些年我的命令行本領在逐步加強,我經常會去搜尋工作中能用的更好的命令行工具。下面就是我現在使用的用於增強原有命令行工具的列表。
怎麼忽略我所做的命令行增強
通常情況下我會用別名將新的增強的命令行工具覆蓋原來的命令(如 cat
和 ping
)。
如果我需要運行原來的命令的話(有時我確實需要這麼做),我會像下面這樣來運行未加修改的原始命令。(我用的是 Mac,你的用法可能不一樣)
$ cat # 忽略叫 "cat" 的別名 - 具體解釋: https://stackoverflow.com/a/16506263/22617
$ command cat # 忽略函數和別名
bat > cat
cat
用於列印文件的內容,如果你平時用命令行很多的話,例如語法高亮之類的功能會非常有用。我首先發現了 ccat 這個有語法高亮功能的工具,然後我發現了 bat,它的功能有語法高亮、分頁、行號和 git 集成。
bat
命令也能讓我在(多於一屏的)輸出里使用 /
搜索(和用 less
搜索功能一樣)。
![Simple bat output](/data/attachment/album/201810/29/204653xppy14y8y4zu6h7s.gif "Sample bat output")
我將別名 cat
指到了 bat
命令:
alias cat='bat'
prettyping > ping
ping
非常有用,當我碰到「糟了,是不是 X 掛了?/我的網不通了?」這種情況下我最先想到的工具就是它了。但是 prettyping
(「prettyping」 可不是指「pre typing」)在 ping
的基礎上加了友好的輸出,這可讓我感覺命令行友好了很多呢。
![prettyping](/data/attachment/album/201810/29/204655zcznq3x70xjexzv3.gif "Sample ping output")
我也將 ping
用別名鏈接到了 prettyping
命令:
alias ping='prettyping --nolegend'
fzf > ctrl+r
在終端里,使用 ctrl+r
將允許你在命令歷史裡反向搜索使用過的命令,這是個挺好的小技巧,儘管它有點麻煩。
fzf
這個工具相比於 ctrl+r
有了巨大的進步。它能針對命令行歷史進行模糊查詢,並且提供了對可能的合格結果進行全面互動式預覽。
除了搜索命令歷史,fzf
還能預覽和打開文件,我在下面的視頻里展示了這些功能。
為了這個預覽的效果,我創建了一個叫 preview
的別名,它將 fzf
和前文提到的 bat
組合起來完成預覽功能,還給上面綁定了一個定製的熱鍵 ctrl+o
來打開 VS Code:
alias preview="fzf --preview 'bat --color "always" {}'"
# 支持在 VS Code 里用 ctrl+o 來打開選擇的文件
export FZF_DEFAULT_OPTS="--bind='ctrl-o:execute(code {})+abort'"
htop > top
top
是當我想快速診斷為什麼機器上的 CPU 跑的那麼累或者風扇為什麼突然呼呼大做的時候首先會想到的工具。我在生產環境也會使用這個工具。討厭的是 Mac 上的 top
和 Linux 上的 top
有著極大的不同(恕我直言,應該是差的多)。
不過,htop
是對 Linux 上的 top
和 Mac 上蹩腳的 top
的極大改進。它增加了包括顏色輸出,鍵盤熱鍵綁定以及不同的視圖輸出,這對理解進程之間的父子關係有極大幫助。
一些很容易上手的熱鍵:
P
—— 按 CPU 使用率排序M
—— 按內存使用排序F4
—— 用字元串過濾進程(例如只看包括 node 的進程)space
—— 錨定一個單獨進程,這樣我能觀察它是否有尖峰狀態
![htop output](/data/attachment/album/201810/29/204657hnfne1peg857gtdq.jpg "Sample htop output")
在 Mac Sierra 上 htop 有個奇怪的 bug,不過這個 bug 可以通過以 root 運行來繞過(我實在記不清這個 bug 是什麼,但是這個別名能搞定它,有點討厭的是我得每次都輸入 root 密碼。):
alias top="sudo htop" # 給 top 加上別名並且繞過 Sierra 上的 bug
diff-so-fancy > diff
我非常確定我是幾年前從 Paul Irish 那兒學來的這個技巧,儘管我很少直接使用 diff
,但我的 git 命令行會一直使用 diff
。diff-so-fancy
給了我代碼語法顏色和更改字元高亮的功能。
![diff so fancy](/data/attachment/album/201810/29/204658r8zajeo2b98ase4b.jpg "Sample diff output")
在我的 ~/.gitconfig
文件里我用了下面的選項來打開 git diff
和 git show
的 diff-so-fancy
功能。
[pager]
diff = diff-so-fancy | less --tabs=1,5 -RFX
show = diff-so-fancy | less --tabs=1,5 -RFX
fd > find
儘管我使用 Mac,但我絕不是 Spotlight 的粉絲,我覺得它的性能很差,關鍵字也難記,加上更新它自己的資料庫時會拖慢 CPU,簡直一無是處。我經常使用 Alfred,但是它的搜索功能也不是很好。
我傾向於在命令行中搜索文件,但是 find
的難用在於很難去記住那些合適的表達式來描述我想要的文件。(而且 Mac 上的 find
命令和非 Mac 的 find
命令還有些許不同,這更加深了我的失望。)
fd
是一個很好的替代品(它的作者和 bat
的作者是同一個人)。它非常快而且對於我經常要搜索的命令非常好記。
幾個上手的例子:
$ fd cli # 所有包含 "cli" 的文件名
$ fd -e md # 所有以 .md 作為擴展名的文件
$ fd cli -x wc -w # 搜索 "cli" 並且在每個搜索結果上運行 `wc -w`
![fd output](/data/attachment/album/201810/29/204700varcm94gce19m91g.png "Sample fd output")
ncdu > du
對我來說,知道當前磁碟空間被什麼佔用了非常重要。我用過 Mac 上的 DaisyDisk,但是我覺得那個程序產生結果有點慢。
du -sh
命令是我經常會運行的命令(-sh
是指結果以「匯總」和「人類可讀」的方式顯示),我經常會想要深入挖掘那些佔用了大量磁碟空間的目錄,看看到底是什麼在佔用空間。
ncdu
是一個非常棒的替代品。它提供了一個互動式的界面並且允許快速的掃描那些佔用了大量磁碟空間的目錄和文件,它又快又准。(儘管不管在哪個工具的情況下,掃描我的 home 目錄都要很長時間,它有 550G)
一旦當我找到一個目錄我想要「處理」一下(如刪除,移動或壓縮文件),我會使用 cmd
+ 點擊 iTerm2 頂部的目錄名字的方法在 Finder 中打開它。
![ncdu output](/data/attachment/album/201810/29/204701qk3aaia5w0z9505o.png "Sample ncdu output")
還有另外一個叫 nnn 的替代選擇,它提供了一個更漂亮的界面,它也提供文件尺寸和使用情況,實際上它更像一個全功能的文件管理器。
我的 du
是如下的別名:
alias du="ncdu --color dark -rr -x --exclude .git --exclude node_modules"
選項說明:
-
--color dark
使用顏色方案 -
-rr
只讀模式(防止誤刪和運行新的 shell 程序) -
--exclude
忽略不想操作的目錄
tldr > man
幾乎所有的命令行工具都有一個相伴的手冊,它可以被 man <命令名>
來調出,但是在 man
的輸出里找到東西可有點讓人困惑,而且在一個包含了所有的技術細節的輸出里找東西也挺可怕的。
這就是 TL;DR 項目(LCTT 譯註:英文里「文檔太長,沒空去讀」的縮寫)創建的初衷。這是一個由社區驅動的文檔系統,而且可以用在命令行上。就我現在使用的經驗,我還沒碰到過一個命令沒有它相應的文檔,你也可以做貢獻。
![TLDR output for 'fd'](/data/attachment/album/201810/29/204703q98ze88c128p93ip.png "Sample tldr output for fd")
一個小技巧,我將 tldr
的別名鏈接到 help
(這樣輸入會快一點……)
alias help='tldr'
ack || ag > grep
grep
毫無疑問是一個強力的命令行工具,但是這些年來它已經被一些工具超越了,其中兩個叫 ack
和 ag
。
我個人對 ack
和 ag
都嘗試過,而且沒有非常明顯的個人偏好,(也就是說它們都很棒,並且很相似)。我傾向於默認只使用 ack
,因為這三個字元就在指尖,很好打。並且 ack
有大量的 ack --bar
參數可以使用!(你一定會體會到這一點。)
ack
和 ag
默認都使用正則表達式來搜索,這非常契合我的工作,我能使用類似於 --js
或 --html
這種標識指定文件類型搜索。(儘管 ag
比 ack
在文件類型過濾器里包括了更多的文件類型。)
兩個工具都支持常見的 grep
選項,如 -B
和 -A
用於在搜索的上下文里指代「之前」和「之後」。
![ack in action](/data/attachment/album/201810/29/204704c433kka72aki0kk7.png "Sample ack output with grep args")
因為 ack
不支持 markdown(而我又恰好寫了很多 markdown),我在我的 ~/.ackrc
文件里加了以下定製語句:
--type-set=md=.md,.mkd,.markdown
--pager=less -FRX
- 安裝指引:ack,ag
- 關於 ack & ag 的更多信息
jq > grep 及其它
我是 jq 的忠實粉絲之一。當然一開始我也在它的語法里苦苦掙扎,好在我對查詢語言還算有些使用心得,現在我對 jq
可以說是每天都要用。(不過從前我要麼使用 grep
或者使用一個叫 json 的工具,相比而言後者的功能就非常基礎了。)
我甚至開始撰寫一個 jq
的教程系列(有 2500 字並且還在增加),我還發布了一個網頁工具和一個 Mac 上的應用(這個還沒有發布。)
jq
允許我傳入一個 JSON 並且能非常簡單的將其轉變為一個使用 JSON 格式的結果,這正是我想要的。下面這個例子允許我用一個命令更新我的所有 node 依賴。(為了閱讀方便,我將其分成為多行。)
$ npm i $(echo $(
npm outdated --json |
jq -r 'to_entries | .[] | "(.key)@(.value.latest)"'
))
上面的命令將使用 npm 的 JSON 輸出格式來列出所有過期的 node 依賴,然後將下面的源 JSON 轉換為:
{
"node-jq": {
"current": "0.7.0",
"wanted": "0.7.0",
"latest": "1.2.0",
"location": "node_modules/node-jq"
},
"uuid": {
"current": "3.1.0",
"wanted": "3.2.1",
"latest": "3.2.1",
"location": "node_modules/uuid"
}
}
轉換結果為:
node-jq@1.2.0
uuid@3.2.1
上面的結果會被作為 npm install
的輸入,你瞧,我的升級就這樣全部搞定了。(當然,這裡有點小題大做了。)
很榮幸提及一些其它的工具
我也在開始嘗試一些別的工具,但我還沒有完全掌握它們。(除了 ponysay
,當我打開一個新的終端會話時,它就會出現。)
你有什麼好點子嗎?
上面是我的命令行清單。你的呢?你有沒有試著去增強一些你每天都會用到的命令呢?請告訴我,我非常樂意知道。
via: https://remysharp.com/2018/08/23/cli-improved
作者:Remy Sharp 選題:lujun9972 譯者:DavidChenLiang 校對:pityonline, wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive