日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

linux shell中的命令自动补全(compgen complete)与 命令行参数解析

發布時間:2025/7/25 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux shell中的命令自动补全(compgen complete)与 命令行参数解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

linux shell中的命令自動補全(compgen complete)與 命令行參數解析

標簽: shell腳本 6661人閱讀 評論(6) 收藏 舉報 分類: linux shell(1)

很多時候,當我們寫一個腳本時,我們總會提供一些可選的命令選項。當可選項比較多的時候,比如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。


解釋的話說的有點多,下面直奔主題了

[plain] view plaincopy
  • 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

    [plain] view plaincopy
  • function?__cmd_bsu()?{??
  • ????local?cur="${COMP_WORDS[COMP_CWORD]}"??
  • ????local?options="$MAIN_COMMAND"??
  • ????COMPREPLY=(?$(compgen?-W?"${options}"?--?${cur})?)??
  • }??

  • [plain] view plaincopy
  • 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函數中完成命令轉發,在各個子命令中詳細解析參數

    [plain] view plaincopy
  • function?bsu()?{??
  • ????case?$1?in??
  • ????pushbaseline)??
  • ????????shift??
  • ????????__parsing_pushbaseline?$@??
  • ????????;;??
  • ????createrepo)??
  • ????????shift??
  • ????????__parsing_createrepo?$@??
  • ????????;;??
  • ????*)??
  • ????????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?$@??
  • }??

  • 解析命令的關鍵一點,對于--xxx=YY的選項,可以使用模式匹配運算符快速得到想要的選項。這里簡單起見,沒有將代碼做很多的形式化,有需要的話,只要利用eval函數,相信難不倒各位看官。


    over,happy new year to everyone!

    總結

    以上是生活随笔為你收集整理的linux shell中的命令自动补全(compgen complete)与 命令行参数解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。