如何修改Bash补全脚本实现ssh服务器名任意子串匹配而非仅前缀匹配
解决方案
你当前的脚本默认使用compgen -W的前缀匹配规则,所以只能匹配输入内容开头的字符串,要实现任意子串匹配,修改匹配逻辑即可,以下是两种可行的修改方案:
方案1:使用grep做子串匹配(推荐,兼容性更好)
直接用grep过滤包含输入子串的候选项,避免特殊字符匹配问题:
_ssh() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts=$(cat "$hosts" | awk -F';' '{print $2}') # 替换原有compgen逻辑,-F表示固定字符串匹配,避免输入特殊字符出错 COMPREPLY=( $(grep -F -- "$cur" <<< "$opts") ) return 0 } complete -F _ssh ssh
如果需要忽略大小写匹配,把grep -F改成grep -iF即可。
方案2:保留compgen,使用过滤参数实现子串匹配
利用compgen的-X过滤参数,只保留包含输入子串的候选项:
_ssh() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts=$(cat "$hosts" | awk -F';' '{print $2}') # !*$cur* 表示反选所有不包含输入子串的项 COMPREPLY=( $(compgen -W "$opts" -X '!*'"$cur"'*' -- ) ) return 0 } complete -F _ssh ssh
修改后输入ssh apac<TAB>就会自动返回所有包含apac子串的主机名列表,符合需求。
内容的提问来源于stack exchange,提问作者jonny
相关产品推荐
相关产品推荐

