bash如何設(shè)置命令補(bǔ)全功能
場(chǎng)景背景
在進(jìn)入docker container的時(shí)候蓝丙,經(jīng)常由于終端窗口大小屬性發(fā)生變化,導(dǎo)致在container里面命令的執(zhí)行結(jié)果輸出非常難看,不能完整的使用外面窗口的大小屬性。
有一個(gè)辦法是蹬癌,使用如下的命令格式來(lái)設(shè)置container內(nèi)的shell終端大小和當(dāng)前外部一致。
$ docker exec -it <container> bash -c "stty cols $COLUMNS rows $LINES && bash
其中環(huán)境變量:$COLUMNS和$LINES就是當(dāng)前終端的屬性虹茶,但是遺憾的是這兩個(gè)變量只能在shell命令符下面使用逝薪,不能在腳本里面調(diào)用。所以上述命令不能放在腳本文件里面執(zhí)行蝴罪,例如:
$ cat entercontainer.sh
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash
$ ./entercontainer.sh <container>
這個(gè)腳本是無(wú)效的董济,變量$COLUMNS和$LINES在此時(shí)是空值。
好在還有另外一個(gè)辦法要门,就是把他們定義成函數(shù)虏肾,設(shè)置在~/.bash_profile里,例如:
entercontainer() {
if [ "X$1" == "X" ]; then
echo "Usage: entercontainer <container> <user>"
return
elif [ "X$2" != "X" ]; then
docker exec -u $2 -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash"
else
docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash"
fi
}
export -f entercontainer
restartcontainer() {
if [ "X$1" == "X" ]; then
echo "Usage: restartcontainer <container>"
return
else
docker stop $1
sleep 5
docker start $1
fi
}
export -f restartcontainer
這里我們定義了一個(gè)entercontainer和restartcontainer兩個(gè)函數(shù)命令暂衡。
這樣我們就可以在shell提示符下面直接運(yùn)行了:
$ entercontainer <container>
這里就有另一個(gè)需求,就是命令補(bǔ)全功能崖瞭,我們希望在shell提示符下面收入entercontainer之后通過(guò)敲tab鍵能夠把所有的container列表給列出來(lái)狂巢,就像'docker exec -it'后敲tab鍵一樣的行為。
$ docker exec -it <tab><tab>
testcontainer1 testcontainer2 ...
辦法就是在目錄/etc/bash_completion.d下放置解析文件书聚,例如:
$ cat /etc/bash_completion.d/entercontainer
_entercontainer()
{
local cur=${COMP_WORDS[COMP_CWORD]}
local all=$(docker ps --format "{{.Names}}")
COMPREPLY=($(compgen -W "$all" -- $cur))
}
complete -F _entercontainer entercontainer
complete -F _entercontainer restartcontainer
- 文件名不重要唧领,不一定要和命令一致,這里保持一致是為了識(shí)別雌续。
- 變量cur是當(dāng)前用戶輸入的值
可以據(jù)此按照前綴匹配過(guò)濾掉container斩个。 - 變量all在此列出所有的container
- 后面兩個(gè)complete 命令,使得entercontainer和restartcontainer都能使用這個(gè)命令不全規(guī)則驯杜。