本文分享自華為云社區《有用的 linux Bash_Completion 命令示例(Steroids 上的 Bash 命令行補全)》,作者:Tiamo_T 。
在 Linux 中,在鍵入命令時,如果按兩次 TAB,它將列出所有以鍵入字符開頭的可用命令。
這不是什么新鮮事,可能你已經知道了。此功能稱為 bash 完成。默認情況下,基本文件和目錄名稱補全在 bash 命令行中可用。
但是,我們可以對這個 bash 補全進行加速,并使用 complete 命令將其提升到一個新的水平。
本教程解釋了我們如何使用可編程完成將自動完成應用于選項和命令的參數。
例如,在輸入 write 命令后,如果按兩次 tab,自動補全會提供用戶列表來執行 write 操作。
$ write [TAB][TAB]bala rajjason randyjohn ritumayla thomasnisha www-data
在以下示例中,它將顯示 te.NET 命令的可用主機名:
$ telnet [TAB][TAB]localhost dev-db fileserver
要在終端中獲得可編程完成,您只需要運行 /etc/bash_completion ,如下所示,
# . /etc/bash_completion
您還可以取消注釋 /etc/bash.bashrc(來自 ubuntu linux 13.04)中的以下行,這樣您就不必顯式運行上述命令,
enable bash completion in interactive shellsif ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fifi
如果你沒有找到這些行和 /etc/bash_completion 文件,那么你只需要通過apt-get安裝名為 bash_completion 的包
1.查看現有的bash-completion
啟用可編程 bash 完成后,定義了一組 bash 完成。命令 complete 用于定義 bash 完成。
要查看現有的 bash 完成,請使用如下所示的 complete 命令。
complete -p | less
在上面的示例中,選項 -p 是可選的。
2. Bash 標準補全列表
Bash 默認為 Linux 用戶提供以下標準補全。
- 1.變量名完成
- 2.用戶名完成
- 3.主機名完成
- 4.路徑名完成
- 5.文件名完成
我們在之前的bash 標準完成文章中討論了這些內容。
3. 定義獲取命令的完成
使用 -c 命令定義完成以獲取可用命令列表作為參數。在以下示例中,完成是為哪個命令定義的,
$ complete -c which$ which [TAB][TAB]Display all 2116 possibilities? (y or n)
如上所示,通過按“y”,所有命令將被列出。
4. 定義獲取目錄的完成
使用選項 d,可以將完成定義為僅獲取目錄名稱作為參數。在以下示例中,為 ls 定義了完成,
$ lscountfiles.sh dir1/ dir2/ dir3/$ complete -d ls$ ls [TAB][TAB]dir1/ dir2/ dir3/
如上所示,按 Tab 僅顯示目錄。
5. 定義獲取后臺作業名稱的完成
使用完成,還可以獲取作業名稱作為命令的參數。選項 j 用于將作業名稱作為參數傳遞給命令作業,如下所示,
$ jobs[1]- Stopped cat[2]+ Stopped sed 'p'$ complete -j ./list_job_attrib.sh$ ./list_job_attrib.sh [TAB][TAB]cat sed
談到后臺作業,您還應該知道如何使用這些示例管理Linux 后臺作業。
6. 前綴和后綴補全
可以使用要添加的所需前綴和要附加實際完成的后綴來定義完成。在以下示例中,為 list_job_attrib.sh 定義了前綴和后綴,
$ jobs [1]+ Stopped cat$ complete -P '">' -S '<"' ./list_job_attrib.sh$ ./list_job_attrib.sh [TAB][TAB]$ ./list_job_attrib.sh ">cat<"
7. 文件名和目錄完成與排除
考慮腳本完成運行,輸出被寫入輸出目錄,如下所示
$ cd output/$ lsall_calls.txt incoming_calls.txt outgoing_calls.txt missed_calls.txtparser_mod.tmp extract.o
在上面,如果您需要忽略 .tmp 和 .o 文件以使用 ls 命令自動完成,那么,
$ export FIGNORE='.tmp:.o'$ complete -f -d ls$ cd output$ ls [TAB][TAB]all_calls.txt incoming_calls.txt outgoing_calls.txt missed_calls.txt
FIGNORE 是包含文件名后綴的 shell 變量,這些后綴在自動完成中被排除。
8. 通過 IFS 拆分字符串以獲得完成值
可以使用 -W 選項提及單詞列表,并使用 IFS 變量中的值進行拆分。然后每個結果單詞都被擴展并顯示為完成,
$ export IFS=" "$ complete -W "bubble quick" ./sort_numbers.sh$ ./sort_numbers.sh [TAB][TAB]bubble quick
如上所述,通過IFS分隔符分割字符串后,單詞得到擴展,因此也可以將這些作為變量,如下所示,
$ echo $SORT_TYPE1bubble$ echo $SORT_TYPE2quick$ complete -W "$SORT_TYPE1 $SORT_TYPE2" ./sort_numbers.sh$ ./sort_numbers.sh [TAB][TAB]bubble quick
9. 編寫你自己的函數來生成完成
它允許您包含一個函數來定義完成。使用 -F 選項,傳遞給完成命令的函數名稱并被執行以生成完成。例如,函數編寫如下所示,
_parser_options(){ local curr_arg; curr_arg=${COMP_wordS[COMP_CWORD]} COMPREPLY=( $(compgen -W '-i --incoming -o --outgoing -m --missed' -- $curr_arg ) );}
在上述函數中,
- 1.COMPREPLY :數組保存按 [TAB][TAB] 后顯示的完成結果
- 2.COMP_WORDS :在命令行上鍵入的單詞數組
- 3.COMP_CWORD :COMP_WORDS 數組的索引,并且可以在命令行上使用此不同位置的單詞進行訪問。
- 4.compgen : -W 保存可能的完成,并根據 $current_arg 選擇相應的參數
文件 parser_option 中存在的此函數的來源如下所示,
$ source parser_option
將此函數鏈接到您的解析器腳本,如下所示,
$ complete -F _parser_options ./parser.pl$ ./parser.pl [TAB][TAB]-i --incoming -o --outgoing -m --missed
如上所示,解析器的選項由函數 _parser_options() 生成。
注意:查看 /etc/bash_completion 以查看可編程完成的更多功能。
10. 當主要不生成任何輔助規范時
如果定義的完成規范沒有生成匹配項,則使用 comp-option 來完成 -o 選項提到的完成。
$ complete -F _count_files -o dirnames ./countfiles.sh
如上所述,完成是用文件 ./countfiles.sh 的 _count_files 函數定義的。如果 _count_files() 函數未生成任何匹配項,則嘗試完成目錄。
$ ls countfiles.sh dir1/ dir2/ dir3/$./countfiles.sh [TAB][TAB]dir1 dir2 dir3