国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統 > 正文

Shell腳本中實現自動補全功能

2024-06-28 13:27:07
字體:
來源:轉載
供稿:網友
Shell腳本中實現自動補全功能

對于linuxer來說,自動補全是再熟悉不過的一個功能了。當你在命令行敲下部分的命令時,肯定會本能地按下Tab鍵補全完整的命令,當然除了命令補全之外,還有文件名補全。

Bash-completion

自動補全這個功能是Bash自帶的,但一般我們會安裝bash-completion包來得到更好的補全效果,這個包提供了一些現成的命令補全腳本,一些基礎的函數方便編寫補全腳本,還有一個基本的配置腳本。但也正如之前說的,這個包不是必須的,只不過可以省些力氣。

bash-completion這個包的安裝位置因不同的發行版會有所區別,但是大致上啟用的原理是類似的,一般會有一個名為bash_completion的腳本,這個腳本會在shell初始化時加載。例如對于RHEL系統來說,這個腳本位于/etc/bash_completion,而該腳本會由/etc/PRofile.d/bash_completion.sh中導入:

 1 # Check for interactive bash and that we haven't already been sourced. 2 [ -z "$BASH_VERSION" -o -z "$PS1" -o -n "$BASH_COMPLETION" ] && return 3  4 # Check for recent enough version of bash. 5 bash=${BASH_VERSION%.*}; bmajor=${bash%.*}; bminor=${bash#*.} 6 if [ $bmajor -gt 3 ] || [ $bmajor -eq 3 -a $bminor -ge 2 ]; then 7     if shopt -q progcomp && [ -r /etc/bash_completion ]; then 8         # Source completion code. 9         . /etc/bash_completion10     fi11 fi12 unset bash bmajor bminor

而在bash_completion腳本中會加載/etc/bash_completion.d下面的補全腳本:

if [[ $BASH_COMPLETION_DIR != $BASH_COMPLETION_COMPAT_DIR && /    -d $BASH_COMPLETION_DIR && -r $BASH_COMPLETION_DIR && /    -x $BASH_COMPLETION_DIR ]]; then    for i in $(LC_ALL=C command ls "$BASH_COMPLETION_DIR"); do        i=$BASH_COMPLETION_DIR/$i        [[ ${i##*/} != @(*~|*.bak|*.swp|/#*/#|*.dpkg*|*.rpm@(orig|new|save)|Makefile*) /            && -f $i && -r $i ]] && . "$i"    donefiunset i

補全腳本的名稱一般就是命令名,這樣比較容易查找:

$ ls i*iconv  iftop  ifupdown  info  iproute2  iptables

內置補全命令

Bash內置有兩個補全命令,分別是compgencompletecompgen命令根據不同的參數,生成匹配單詞的候選補全列表,例如:

$ compgen -W 'hi hello how world' hhihellohow

compgen最常用的選項是-W,通過-W參數指定空格分隔的單詞列表。h即我們在命令行當前鍵入的單詞,執行完后會輸出候選的匹配列表,這里是以h開頭的所有單詞。

complete命令的參數有點類似compgen,不過它的作用是說明命令如何進行補全,例如同樣使用-W參數指定候選的單詞列表:

$ complete -W 'Word1 word2 word3 hello' foo$ foo w<Tab>$ foo word<Tab>word1  word2  word3

我們還可以通過-F參數指定一個補全函數:

$ complete -F _foo foo

現在鍵入foo命令后,會調用_foo函數來生成補全的列表,完成補全的功能,這一點正是補全腳本實現的關鍵所在,我們會在后面介紹。

補全相關的內置變量

除了上面的兩個補全命令外,Bash還有幾個內置的變量用來輔助補全功能,這里主要介紹其中三個:

  • COMP_WORDS: 類型為數組,存放當前命令行中輸入的所有單詞;
  • COMP_CWORD: 類型為整數,當前光標下輸入的單詞位于COMP_WORDS數組中的索引;
  • COMPREPLY: 類型為數組,候選的補全結果;
  • COMP_WORDBREAKS: 類型為字符串,表示單詞之間的分隔符;
  • COMP_LINE: 類型為字符串,表示當前的命令行輸入;

例如我們定義這樣一個補全函數_foo:

$ function _foo(){     echo -e "/n"     declare -p COMP_WORDS    declare -p COMP_CWORD     declare -p COMP_LINE     declare -p COMP_WORDBREAKS}$ complete -F _foo foo

假設我們在命令行下輸入以下內容,再按下Tab鍵補全:

$ foo bdeclare -a COMP_WORDS='([0]="foo" [1]="b")'declare -- COMP_CWORD="1"declare -- COMP_LINE="foo b"declare -- COMP_WORDBREAKS="     

對著上面的結果,我想應該比較容易理解這幾個變量。當然正如我們之前據說,Bash-completion包并非是必須的,補全功能是Bash自帶的。

編寫腳本

補全腳本分成兩個部分:編寫一個補全函數和使用complete命令應用補全函數。后者的難度幾乎忽略不計,重點在如何寫好補全函數。難點在,似乎網上很少與此相關的文檔,但是事實上,Bash-completion自帶的補全腳本是最好的起點,可以挑幾個簡單的改改基本上就可以使用了。

一般補全函數(假設這里依然為_foo)都會定義以下兩個變量:

local cur prev

其中cur表示當前光標下的單詞,而prev則對應上一個單詞:

cur="${COMP_WORDS[COMP_CWORD]}"prev="${COMP_WORDS[COMP_CWORD-1]}"

初始化相應的變量后,我們需要定義補全行為,即輸入什么的情況下補全什么內容,例如當輸入-開頭的選項的時候,我們將所有的選項作為候選的補全結果:

local opts="-h --help -f --file -o --output"if [[ ${cur} == -* ]] ; then        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )        return 0fi

不過再給COMPREPLY賦值之前,最好將它重置清空,避免被其它補全函數干擾。

現在完整的補全函數是這樣的:

function _foo() {    local cur prev opts    COMPREPLY=()    cur="${COMP_WORDS[COMP_CWORD]}"    prev="${COMP_WORDS[COMP_CWORD-1]}"    opts="-h --help -f --file -o --output"    if [[ ${cur} == -* ]] ; then        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )        return 0    fi}

現在在命令行下就可以對foo命令進行參數補全了:

$ complete -F _foo foo$ foo --f        --file    -h        --help    -o        --output

當然,似乎我們這里的例子沒有用到prev變量。用好prev變量可以讓補全的結果更加完整,例如當輸入--file之后,我們希望補全特殊的文件(假設以.sh結尾的文件):

case "${prev}" in    -f|--file)        COMPREPLY=( $(compgen -o filenames -W "`ls *.sh`" -- ${cur}) )        ;;esac

現在再執行foo命令,--file參數的值也可以補全了:

$ foo --file<Tab>a.sh b.sh c.sh

安裝補全腳本

如果安裝了Bash-completion包,可以將補全腳本放在/etc/bash_completion.d目錄下,或者放到~/.bash_completion文件中。如果沒有安裝Bash-completion包,可以把補全腳本放到~/.bashrc或者其它能被shell加載的初始化文件中。

原文地址 http://www.it165.net/os/html/201212/4208.html


上一篇:dpdk l2fwd

下一篇:段頁式存儲

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 赤城县| 阳曲县| 黄龙县| 永吉县| 新绛县| 论坛| 宜春市| 桓台县| 武隆县| 河东区| 滦南县| 江安县| 银川市| 民乐县| 新龙县| 临湘市| 怀化市| 繁昌县| 宝丰县| 白河县| 尤溪县| 深水埗区| 雷波县| 曲沃县| 会昌县| 策勒县| 德安县| 安塞县| 穆棱市| 昌乐县| 柘城县| 扎囊县| 民丰县| 林西县| 临桂县| 梅河口市| 盐源县| 和静县| 安阳市| 安西县| 遵化市|