灵感来自https://github.com/CumulusNetworks/NetworkDocopt
基本技巧是将帮助文本、PS1(扩展)和原始命令打印到stderr
,然后将完成选项打印到stdout
.
这是在 bash 中获取的代码片段,以将完成函数添加到telnet
. 它将调用一个 ruby 脚本(称为p.rb
)来生成实际的完成输出。
_telnet_complete()
{
COMPREPLY=()
COMP_WORDBREAKS=" "
local cur=${COMP_WORDS[COMP_CWORD]}
local cmd=(${COMP_WORDS[*]})
local choices=$(./p.rb ${cmd[*]} --completions ${COMP_CWORD} ${PS1@P})
COMPREPLY=($(compgen -W '${choices}' -- ${cur} ))
return 0
}
complete -F _telnet_complete telnet
这是一个实现p.rb
:
#!/usr/bin/env ruby
ip = ""
out_ps1 = []
out_args = []
state = :init
completion_req = false
ARGV.each do |e|
case state
when :init
if e == "--completions"
completion_req = true
state = :complte
else
out_args << e
if /^\d+\.\d+\.\d+\.\d+$/ =~ e
ip = e
end
end
when :complte
state = :ps1
when :ps1
out_ps1 << e
end
end
routes = {
"10.10.10.10" => "routerA",
"10.10.10.11" => "routerB",
}
if completion_req
$stderr.puts ""
routes.each do |k, v|
if k[0..ip.size] == ip or ip.size == 0
$stderr.puts "#{k} - #{v}"
$stdout.puts k
end
end
$stderr.write "#{out_ps1.join(" ")}#{out_args.join(" ")} "
exit 0
end
例子:
$ telnet <tab>
10.10.10.10 - routerA
10.10.10.11 - routerB
$ telnet 10.10.10.1