在 中zsh
,我可以自动完成来自 的主机名/etc/hosts
,即:
ssh f<TAB>
将为以 开头的主机提供补全f
。
这是在以下位置配置的/usr/share/zsh/functions/Completion/Unix/_hosts
:
local ipstrip='[:blank:]#[^[:blank:]]#'
zstyle -t ":completion:${curcontext}:hosts" use-ip && useip=yes
[[ -n $useip ]] && ipstrip=
if (( ${+commands[getent]} )); then
_cache_hosts=(${(s: :)${(ps:\t:)${(f)~~"$(_call_program hosts getent hosts 2>/dev/null)"}##${~ipstrip}}})
else
_cache_hosts=(${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##${~ipstrip}}})
fi
....
_hosts=( "$_cache_hosts[@]" )
但是,它仅在/etc/hosts
文件格式为“IP”“主机名”时才有效,即:
192.168.1.4 foo.mydomain.com
如果 IP 丢失,它将无法工作:
foo.mydomain.com
如何修改完成脚本,以便没有 IP 的主机名也完成?
没有 IP 的主机名补全/etc/hosts
在bash_completion
.所以我只是想在zsh
.
答案1
我建议这样做,这将使用您的(和系统的)ssh 已知主机文件:
zstyle -e ':completion:*:(ssh|scp|sftp|rsh|rsync):hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%[# ]*}//,/ })'
如果您仍然想使用 /etc/hosts 代替:
strip='[:blank:]#[^[:blank:]]#'
zstyle -e ':completion:*:(ssh|scp|sftp|rsh|rsync):hosts' hosts 'reply=(${(s: :)${(ps:\t:)${${(f)~~"$(</etc/hosts)"}%%\#*}##${~strip}}})'
祝你好运!
答案2
添加过滤功能/usr/share/zsh/functions/Completion/Unix/_hosts
:
provide_missing_ip() {
while read x ; do
set -- $x
if [ ! "$1" ] || [ "${1%%[^#]*}" ] || [ "$2" ] ; then
echo "$x"
else
ip=`dig +short $2`
[ "$ip" ] || ip="240.0.0.0"
printf "%s\t%s\n" $1 $2
fi
done
}
怎么运行的:
- 如果有两个条目、一个空白或一个注释,则只需输出它们即可。
- 如果只有主机名,请尝试提供知识产权地址与
dig
. - 如果做不到这一点,(不应该发生,但假设这是出于测试目的而故意伪造的主机名),请使用无害的虚拟主机名知识产权地址“240.0.0.0“, (看班德拉米的回答 ”相当于 /dev/null 的 IP 地址”)。
使用新函数来解析麻烦的完成代码中的getent
or的输出:< /etc/hosts
if (( ${+commands[getent]} )); then
_cache_hosts=(${(s: :)${(ps:\t:)${(f)~~"$(_call_program hosts getent hosts 2>/dev/null | provide_missing_ip )"}##${~ipstrip}}})
else
_cache_hosts=(${(s: :)${(ps:\t:)${${(f)~~"$(provide_missing_ip </etc/hosts)"}%%\#*}##${~ipstrip}}})
fi
答案3
该hosts
文件必须采用 格式IP_address canonical_hostname [aliases...]
,因此您的方法应该是修复您的主机文件,而不是让一个程序片段解决损坏的文件。如果您的程序损坏了,其他程序也可能会出现问题hosts
,因此这将是您的用例的唯一合理的解决方案。如果您的目标是动态 IP,并且您不想使用上面提供的任何更好的解决方法,请考虑编写一个脚本,hosts
根据此更改的地址动态更改您的 IP。