linux shell中的命令自動補全(compgen complete)與 命令列引數解析
很多時候,當我們寫一個指令碼時,我們總會提供一些可選的命令選項。當可選項比較多的時候,比如git, 如果能夠提供命令自動補全,無疑是錦上添花的事。而且個人認為,這種方式,比採用將命令做成選擇選單要更好一些。
假設我們現在這樣一個指令碼,指令碼執行命令時bsu, 類似git,指令碼有兩個一級主命令pushbaseline, createrepo,然後這兩個一級主命令下還有若干選項
pushbaseline --qcom --mtk --name=(NX01, NX02) #要求 --qcom --mtk不能同時出現,- -name=xxx可以與前面任意一個選項同時出現
createrepo --git --repo --name=xxx --auth=(W, R, RW) # 同上,這裡--git, --repo不能同時出現。 後面兩個選項隨意
正式行動之前我們做一個簡單的需求分析,正所謂不做需求分析就幹活,“加班沒日夜, 累死也枉然”
以pushbaseline為例,這裡要求--qcom --mtk不能同時出現,如果直接在指令碼中實現,就要判斷之前輸入中有沒有輸入--qcom,如果有輸入,就不能再把--mtk作為命令自動補全的候選者。這種邏輯很複雜,對shell指令碼不熟的人,只能望洋興嘆——“呵呵”。
事實上,從實際情況來看的話,為什麼不能同時出現,因為它們都屬於某個屬相的描述,所以這裡簡單的改為--platfrom=(qcom, mtk),問題就巧妙解決了。
下面開始寫指令碼,上面將--qcom --mtk 改編為--platform=(qcom,mtk),缺少了簡單選項,為此再額外加一個 --multi
自動補全,linux提供了兩個重要命令 compgen, complete
命令:compgen -W "aa ab bb cc" -- “a”
表示從"aa ab bb cc" 匹配出以“a”開頭的單詞
這條命令的返回結果就是 “aa ab”。
命令:complete -F __cmd_HUB bsu
表示當執行bsu命令時,自動補全的候選單詞由函式__cmd_HUB計算得到,具體的承載容器是變數COMPREPLY
特別說明一下,像這樣的complete -F XXX ./test.sh 也是合法的。如果XXX的計算後得到COMPREPLY=(aa bb cc), 則輸入 ./test.sh 之後, 按tab鍵,可以自動彈出候選選項aa bb cc。
解釋的話說的有點多,下面直奔主題了
function __cmd_HUB() {
#$COMP_CWORD是系統自動變數,表示當前命令單詞索引。 0表示第一個單詞,也就是bsu。
case $COMP_CWORD in
0) #仍在完成根命令,這裡不需要處理
;;
1) #根命令已經完成,這裡開始補充一級主命令
#${COMP_WORDS[0]}是根命令,在這個例子中就是bsu
eval __cmd_${COMP_WORDS[0]}
;;
2|*)#一級主命令已經完成,這裡開始補充一級主命令的選項
#${COMP_WORDS[1]}是一級主命令,在這個例子中就是pushbaseline或者createrepo
eval __cmd_${COMP_WORDS[1]}
;;
esac
}
complete -F __cmd_HUB bsu
如果有同學對eval命令不瞭解,就找度娘吧。
上面我們做了一個約定,要獲取命令<command>的選項,則總是呼叫函式__cmd_<command>獲得,因此下面就要實現__cmd_bsu, __cmd_pushbaseline, __cmd_createrepo
function __cmd_bsu() {
local cur="${COMP_WORDS[COMP_CWORD]}"
local options="$MAIN_COMMAND"
COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
}
function __cmd_pushbaseline() {
local cur="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=()
case $cur in
--name=*)
local options="NX01 NX02"
COMPREPLY=( $(compgen -W "${options}" -- ${cur#--name=}) )
;;
--platform=*)
local options="qcom mtk"
COMPREPLY=( $(compgen -W "${options}" -- ${cur#--platform=}) )
;;
*)
local options="--platform= --name= --multi"
COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
;;
esac
}
命令自動補全都到此為止,篇幅有點長了,下面長話短說,直接處理命令,以命令 bsu pushbaseline --platform=qcom --name=NX01 --multi 為例
在bsu函式中完成命令轉發,在各個子命令中詳細解析引數
function bsu() {
case $1 in
pushbaseline)
shift
__parsing_pushbaseline [email protected]
;;
createrepo)
shift
__parsing_createrepo [email protected]
;;
*)
echo "unknown command $1"
;;
esac
}
function __parsing_pushbaseline() {
while [ $# -gt 0 ]; do
case $1 in
--platform=*)
local platform=${1#--platform=}
;;
--name=*)
local name=${1#--name=}
;;
--multi)
local multi=1
;;
esac
shift
done
bsu_pushbaseline $platform $name $multi
}
function bsu_pushbaseline()
{
echo bsu_pushbaseline [email protected]
}
解析命令的關鍵一點,對於--xxx=YY的選項,可以使用模式匹配運算子快速得到想要的選項。這裡簡單起見,沒有將程式碼做很多的形式化,有需要的話,只要利用eval函式,相信難不倒各位看官。
over,happy new year to everyone!
相關推薦
linux shell中的命令自動補全(compgen complete)與 命令列引數解析
很多時候,當我們寫一個指令碼時,我們總會提供一些可選的命令選項。當可選項比較多的時候,比如git, 如果能夠提供命令自動補全,無疑是錦上添花的事。而且個人認為,這種方式,比採用將命令做成選擇選單要更好一些。 假設我們現在這樣一個指令碼,指令碼執行命令時bsu, 類似gi
Linux Shell 命令自動補全(各方資料彙總補全版)
在下所在的公司定義了一種路徑,配合自定義的 loader 命令;遂命令在下完成自定義路徑的自動補全需求。 關於Linux Shell命令自動補全已有的一些優秀 blog 沒有開花的樹的《詳解Linux Shell命令自動補全》 這篇文章講
詳解Linux Shell命令自動補全
在Linux命令列下,輸入字元後,按兩次Tab鍵,shell就會列出以這些字元打頭的所有可用命令。如果只有一個命令匹配到,按一次Tab鍵就自動將這個命令補全。比如,想更改密碼,但只記得這個命令前幾個字母是pass。這時候,按Tab鍵,shell就自動輸出 passwd 命令,
Linux Shell命令自動補全以及上下條命令
tab鍵 上一條 一個 linux ron 好用 默認 inux 輸入 在Linux命令行下,輸入字符後,按兩次Tab鍵,shell就會列出以這些字符打頭的所有可用命令。如果只有一個命令匹配到,按一次Tab鍵就自動將這個命令補全。當然,除了命令補全,還有路徑、文件名補全。這
Linux Shell--改變目錄/自動補齊/命令列的歷史記錄/快捷鍵
改變目錄 ‘cd’(改變目錄,change directory) ‘~’就是您的 home 目錄的簡寫形式。理論上,這也可以應用在命令’cd’上。無論當前路徑在哪裡,cd ~ 將回到您的 home 目錄。其實還可以簡化,只要鍵入 cd ,就可以返回 ho
Python命令行加TAB補全(2.6)
python 自動補全 tab 首先,要找到Python的路徑[[email protected]/* */ python2.6]$ python Python 2.6.6 (r266:84292, Nov 22 2013, 12:16:22) [GCC 4.4.7 20120313
ssh+tab 命令自動補全主機名
ssh tab 主機名補全對於運維來講,“快”這個字是必備的,所以,在你手下的若幹肉雞一定不計其數,但是真的管理起來要跳轉到哪臺機器上還真是要找下的。尤其是針對跳板機這類的系統,肉雞一多100+臺。。。看到你眼睛都掉下來,還不如來個自動補全主機名來的實在。so ... 怎麽操作呢?其實步驟很簡單:前提主機間做
oracle中日期自動補全,沒有資料自動補0
原文地址:https://blog.csdn.net/weixin_36150793/article/details/81607574 oracle中日期自動補全,沒有資料自動補0 1. 描述 最近在專案中遇到一個問題,在進行oracle相關查詢操作的時候,查詢某個月的資料,這個月中某些日期沒有
redis集合/有序集合在電商中應用-自動補全
類似 淘寶 比如 搜尋框中輸入 :書 :下拉框中出現: '書包女士', '書包男款', '書大', '書包女贈送韓版', '書皮紙韓國小清新', '書斤', '書包女雙肩包學生簡約', '書雙肩包', '書包學生', '書籍出版' 使用者可以使用 上下箭頭 或滑鼠 選取 大致有兩種思
Mysql命令自動補全-全網最全-支持語法高亮
過大 strong none src feature column 電子 all 困難 方法一 今天再推薦一款命令行神器 - Mycli.Mycli 是一個MySQL命令行客戶端工具,具有自動完成和語法突出顯示功能。它是由印度人基於python開發的一個工具,適合初學者或者
kubectl命令自動補全功能
share -o ffffff img water process 避免 shadow 命令補全 我們在管理k8s集群的時候,避免不了使用kubectl命令工具,但是該命令還是挺復雜的,使用中也記不住那麽多的api選項,故這裏介紹一下kubectl命令補全工具的安裝。 1:
Mac 下 git 命令自動補全
一. 安裝 bash-completion brew install bash-completion 安裝成功後提示: ==> Caveats Add the following line to your ~/.bash_profile: [ -f /usr/lo
Zend Studio 中安裝自動補全emmet外掛的方法
1. 開啟Zend Studio,點選 Help --> Install New Software,如下圖: 2. 在Work With中填入如下地址:http://emmet.io/eclipse/updates/ ,回車,選擇某個版本的emmet,如
linux下mysql的自動補全工具mycli
習慣了在bash命令列下的tab自動補全功能,在linux下安裝mysql,或者是mariadb後發現不能自動補全,這就讓我很難受,所以我找到了一個很強大的工具可以實現自動補全 這個工具就是mycli,這個工具很強大,先來看一下 我用的是centos7下的ma
kubectl 命令自動補全
在k8s 1.3版本之前,設定kubectl命令自動補全是通過以下的方式: source ./contrib/completions/bash/kubectl 1 source./con
vscode react中標籤自動補全 vscode jsx語法自動補全html標籤
能找到我這個文章的八成就是前端了,前端都習慣了程式碼自動補全,猛一下的自己打閉合標籤很不習慣, 再說了,VSCODE多強大啊,怎麼可能沒有解決辦法,方法如下: 檔案--首選項--設定--使用者設定 在使用者設定新增 "emmet.includeLanguages":
Mac版git命令自動補全
在Mac上安裝了git之後,發現命令不能自動補全,使用起來非常不方便,本文介紹怎麼讓git命令能夠自動補全。 1)首先確保有brew 2)執行以下命令安裝bash-completion brew install bash-completion 3)執行以下命令, b
Eclipse中程式碼自動補全配置
最簡單的修改方式是:Windows——>Preferences——>Java-->Editor-->Content Asist,在Auto activation triggers for Java後面的文字框裡只有一個“.”。現在你將其改為“.abcdefghijklmn
bash的按TAB鍵自動補全(自動完成)的原理與擴充套件
最近在用原始碼安裝ceph,發現命令不能自動補全,然後找到了下面這篇文章,寫的很好~轉載一下~ 原始碼安裝ceph命令沒法自動補全的解決方法:把ceph-deploy安裝的可以自動補全的系統裡/etc/bash_completion.d下ceph的檔案scp到原始碼安裝對應
Vim UltiSnips自動補全 (Python強依賴)
想要Vim像Sublime一樣快速程式設計,就需要各種好的snippets快速生成一段預備好的程式碼。一般常用的外掛是UltiSnips作為生成程式碼的引擎,Vim-snippets外掛作為各種語言的常用語句包。 注意:此外掛極其依賴Python特定版本,一旦本地pytho