你最常用的一個 linux 命令是什麼?為什麼?

2020 年了,真的沒必要再終端裡一個字一個字敲命令了,有更酷炫的方式。分享下我在今年年最常用的一個命令,task,命令行任務管理。

服務端命令太長記輸入慢怎麼辦?用的少的命令記不住怎麼辦?你需要任務管理器,將你命令行各種常見的冗餘的任務管理起來,然後敲 2-3 個字母就能啟動它(點擊播放下面動圖):

你最常用的一個 linux 命令是什麼?為什麼?

基本日常各種長難命令,什麼 git 操作啊,常用主機間 ssh 跳來跳去啊,項目的編譯,測試和發佈啊,別人每次還需要重新敲一遍,或者把歷史調出來,四處修改一番,有時候還改錯了。而你現在只需要敲 2-3 個字母就運行了,像溜冰一般的流暢。

平時就連 task 四個字你都可以省略,綁定到 F5 上去,用法:

<code>cd ~/github
git clone --depth 1 https://github.com/skywind3000/asynctasks.vim
ln -s ~/github/asynctasks.vim/bin/asynctask ~/bin/<code>

然後記得把你的 ~/bin 目錄加入 $PATH,最後在你的 .bashrc 中加一行:

<code>alias task='asynctask -f'/<code>

妥了,然後添加任務,編輯:~/.config/asynctask/tasks.ini 全局任務配置:

<code>[git-fetch-master]
command=git fetch origin master
cwd=<root>

[git-checkout]
command=git checkout $(?branch)
cwd=<root>/<root>/<code>

類似這樣,然後輸入 task 命令,就能運行上面的任務了,cwd 字段是命令運行的目錄, <root> 代表項目根目錄(有 .git 和 .svn 那個目錄),不寫的話就是當前目錄,如果命令包含 $(?xxx) 的內容,運行前就會讓用戶輸入 xxx,然後替換。/<root>

局部任務定義在各個項目文件夾下的 .tasks 中,作用所有子目錄,完成針對項目的一些編譯,測試,發佈等日常任務,就是每天敲著你手累的命令,現在可以只用 2-3 個字母就重複執行了。

我平時連 task 幾個字都懶得敲,因為把它綁到 F5 上了,把下面代碼放入 .bashrc:

<code>bind '"\\e[15~":"task\\n"'/<code>

用 zsh 的話,把用下面配置:

<code>bindkey -s '\\e[15~' 'task\\n'/<code>

然後每次按 F5 就運行 task 命令了,更少擊鍵,記得使用前先安裝 fzf,不然就只能:

<code>asynctask git-fetch-master/<code>

這樣輸入完整命令了,安裝了 fzf 以後,就可以模糊匹配輸入命令。

基本可以把反覆用到的 shell 命令分類保存,特別是一些又臭又長的命令,現在只需要輕輕的敲 2-3 個字母就成了。

這裡有一份命令配置例子:skywind3000/asynctasks.vim

在 Vim 裡也可以這麼用(點擊播放下面動圖):

你最常用的一個 linux 命令是什麼?為什麼?

你當然也可以把常用任務綁定到 F1-F12 上,不用每次輸入。

--

不要自作聰明的著急科普 fish shell 了,這是 fish 和 zsh 裡沒有的新東西。更不是歷史搜索。這套任務系統要說像的話,你們沒發現它更像 vscode 的任務系統麼?我拓展了它的用途,讓它變得更為通用和靈活。

這本質上是對裸命令進行二次抽象,這個抽象會給你帶來意想不到的便利,比如你想編譯和執行某個文件,那麼可以把他們的語義統一成 file-build 和 file-run:

放到全局配置裡

<code>[file-build]
command:c,cpp=gcc -O2 -Wall "$(VIM_FILEPATH)" -o "$(VIM_PATHNOEXT)" -lstdc++ -lm -msse3
command:go=go build -o "$(VIM_PATHNOEXT)" "$(VIM_FILEPATH)"
command:make=make -f "$(VIM_FILEPATH)"
cwd=$(VIM_FILEDIR)

[file-run]
command="$(VIM_FILEPATH)"
command:c,cpp="$(VIM_PATHNOEXT)"
command:go="$(VIM_PATHNOEXT)"
command:python=python "$(VIM_FILENAME)"
command:javascript=node "$(VIM_FILENAME)"
command:sh=sh "$(VIM_FILENAME)"
command:lua=lua "$(VIM_FILENAME)"
command:perl=perl "$(VIM_FILENAME)"
command:ruby=ruby "$(VIM_FILENAME)"
cwd=$(VIM_FILEDIR)/<code>

不同的文件能夠執行不同的命令進行編譯。那麼,我們語義就可以統一成:

<code>asynctask file-build xxx    # 編譯文件
asynctask file-run xxx # 運行文件/<code>

你只需要記這樣一個任務名即可,不需要管理細節,還可以把它配置在你喜歡的任何編輯器上,快捷鍵操作。上面配置裡的 $(...) 的宏以 VIM 開頭是為了兼容同名 vim 插件的配置,並不是需要 Vim 才能運行。

項目編譯

配置任務時可以添加經常可以把下面配置添加到全局任務中:

<code>[project-build]
command=make
# 設置在當前項目的根目錄處運行 make
cwd=$(VIM_ROOT)

[project-run]
command=make run
# <root> 是 $(VIM_ROOT) 的別名,寫起來容易些
cwd=<root>
output=terminal/<root>/<root>/<code>

以往你命令行編譯項目時,勢必要回到項目根目錄,再運行 make 什麼的,設置好了 cwd 字段以後,你可以再某項目任意一級子目錄裡運行:

<code>asynctask project-build/<code>

它都會自動幫你向上搜尋項目根目錄的標記(.git, .svn, .project 可配置),並記錄在宏 <root> 裡,命令設置了 cwd=<root> 以後,就會自動跑到項目根路徑處運行,不用你每次 cd ../../.. 一大堆。/<root>/<root>

能夠流暢無阻礙的執行:“編輯/編譯/測試” 循環,是提高你編程效率最有效的方法,所以我們把上面兩個任務綁定到 F7 和 F8:

<code>bind '"\\e[18~":"asynctask project-build\\n"'
bind '"\\e[19~":"asynctask project-run\\n"'/<code>

那麼你在某個項目任意一級子目錄下面就能 F7 編譯項目,F8 運行項目了,命令都不用敲。

不同的項目,構建系統不同,有的用 cmake 有的用 gnu make,假設我係統裡大部分項目都是 gnu make 的,那麼把上面 gnu make 的任務配置成全局的就行,但是我的 A 項目中使用 msbuild 進行構建,難道要配置一個 project-build-msbuild 的任務麼?

任務適配

並不需要,我只需要在項目 A 的根目錄處放一個 .tasks 文件:

<code>[project-build]
command=vcvars32 > nul && msbuild build/StreamNet.vcxproj /property:Configuration=Debug /nologo /verbosity:quiet
cwd=<root>
errorformat=%f(%l):%m

[project-run]
command=build/Debug/StreamNet.exe
cwd=<root>
output=terminal/<root>/<root>/<code>

因為本地任務比全局任務有更高優先級,那麼只要我在 A 項目下面任意一層子目錄內運行:

<code>asynctask project-build
asynctask project-run/<code>

就能用上級目錄 .tasks 文件中配置的具體命令,調用 msbuild 編譯當前項目了:


你最常用的一個 linux 命令是什麼?為什麼?


使用 cmake 的項目也一樣,局部重新定義 project-build/run 等任務的內容

比如你在 project A 下面 src 目錄裡面很深的一級子目錄,你不需要回到根目錄,因為命令已經寫清楚了自己的運行位置,運行時會臨時回到項目根目錄處運行,編譯完你也不用一級級返回。

具體命令經過抽象後,不需要記住每個項目複雜的構建命令細節,只需記住統一的任務名稱即可。在不同的項目中可以保持同樣的操作習慣,不需要回想這個項目到底是用什麼編譯的,還還可以把它配置到 F7,F8 上面,熱鍵任然不用改,不論你處在什麼類型的項目下面,你的習慣不用改,你的工作流不會中斷。

或者配置到你熟悉的編輯器上,就像 NotePad++ 這樣原始的編輯器也有 NppExec 的插件讓你配置外部工具,那麼當你配置到編輯器上以後,你就能和命令行一起使用完全相同的語義,對重複度高的工作進行統一的抽象了。

這就是全局任務和局部任務搭配的黑魔法。其他還有很多技巧,為同一個任務配置不同的 profile ,指定是 debug 模式,還是 release 模式,還是 gdb 模式,同樣不用更改任務的名字,就能區別不同的 profile,具體見項目文檔吧。


分享到:


相關文章: