本文分享自华为云社区《有用的 Linux Bash_Completion 命令示例(Steroids 上的 Bash 命令行补全)》,作者:Tiamo_T 。
在 Linux 中,在键入命令时,如果按两次 TAB,它将列出所有以键入字符开头的可用命令。
这不是什么新鲜事,可能你已经知道了。此功能称为 bash 完成。默认情况下,基本文件和目录名称补全在 bash 命令行中可用。
但是,我们可以对这个 bash 补全进行加速,并使用 complete 命令将其提升到一个新的水平。
本教程解释了我们如何使用可编程完成将自动完成应用于选项和命令的参数。
例如,在输入 write 命令后,如果按两次 tab,自动补全会提供用户列表来执行 write 操作。
$ write [TAB][TAB]bala raj jason randy john ritu mayla thomas nisha www-data
复制代码$ telnet [TAB][TAB]localhost dev-db fileserver
复制代码# . /etc/bash_completion
复制代码 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 fi fi
复制代码1. 查看现有的 bash-completion
启用可编程 bash 完成后,定义了一组 bash 完成。命令 complete 用于定义 bash 完成。
要查看现有的 bash 完成,请使用如下所示的 complete 命令。
complete -p | less
复制代码2. Bash 标准补全列表
Bash 默认为 Linux 用户提供以下标准补全。
- 变量名完成
- 用户名完成
- 主机名完成
- 路径名完成
- 文件名完成
我们在之前的 bash 标准完成文章中讨论了这些内容。
3. 定义获取命令的完成
使用 -c 命令定义完成以获取可用命令列表作为参数。在以下示例中,完成是为哪个命令定义的,
$ complete -c which$ which [TAB][TAB] Display all 2116 possibilities? (y or n)
复制代码4. 定义获取目录的完成
使用选项 d,可以将完成定义为仅获取目录名称作为参数。在以下示例中,为 ls 定义了完成,
$ lscountfiles.sh dir1/ dir2/ dir3/ $ complete -d ls $ ls [TAB][TAB] dir1/ dir2/ dir3/
复制代码5. 定义获取后台作业名称的完成
使用完成,还可以获取作业名称作为命令的参数。选项 j 用于将作业名称作为参数传递给命令作业,如下所示,
$ jobs[1]- Stopped cat [2]+ Stopped sed 'p' $ complete -j ./list_job_attrib.sh $ ./list_job_attrib.sh [TAB][TAB] cat sed
复制代码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<"
复制代码考虑脚本完成运行,输出被写入输出目录,如下所示
$ cd output/$ ls all_calls.txt incoming_calls.txt outgoing_calls.txt missed_calls.txt parser_mod.tmp extract.o
复制代码$ 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
复制代码8. 通过 IFS 拆分字符串以获得完成值
可以使用 -W 选项提及单词列表,并使用 IFS 变量中的值进行拆分。然后每个结果单词都被扩展并显示为完成,
$ export IFS=" "$ complete -W "bubble quick" ./sort_numbers.sh $ ./sort_numbers.sh [TAB][TAB] bubble quick
复制代码$ echo $SORT_TYPE1bubble $ echo $SORT_TYPE2 quick $ complete -W "$SORT_TYPE1 $SORT_TYPE2" ./sort_numbers.sh $ ./sort_numbers.sh [TAB][TAB] bubble quick
复制代码它允许您包含一个函数来定义完成。使用 -F 选项,传递给完成命令的函数名称并被执行以生成完成。例如,函数编写如下所示,
_parser_options(){ local curr_arg; curr_arg=${COMP_WORDS[COMP_CWORD]} COMPREPLY=( $(compgen -W '-i --incoming -o --outgoing -m --missed' -- $curr_arg ) ); }
复制代码- COMPREPLY :数组保存按 [TAB][TAB] 后显示的完成结果
- COMP_WORDS :在命令行上键入的单词数组
- COMP_CWORD :COMP_WORDS 数组的索引,并且可以在命令行上使用此不同位置的单词进行访问。
- 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
复制代码注意:查看 /etc/bash_completion 以查看可编程完成的更多功能。
10. 当主要不生成任何辅助规范时
如果定义的完成规范没有生成匹配项,则使用 comp-option 来完成 -o 选项提到的完成。
$ complete -F _count_files -o dirnames ./countfiles.sh
复制代码$ ls countfiles.sh dir1/ dir2/ dir3/ $./countfiles.sh [TAB][TAB] dir1 dir2 dir3
复制代码