1. 程式人生 > >linux shell中的命令自動補全(compgen complete)與 命令列引數解析

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命令行加TAB2.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