zsh: SSH의 완료 규칙

zsh: SSH의 완료 규칙

에서는 다음과 같이 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가 없는 호스트 이름도 완성되도록 완성 스크립트를 어떻게 수정합니까?

/etc/hosts에는 IP에 대한 호스트 이름 완성이 없습니다 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
}

작동 방식:

  1. 두 개의 항목(공백 또는 주석)이 있는 경우 이를 출력하십시오.
  2. 호스트 이름만 있는 경우 제공해 보세요.지적 재산권주소와 dig.
  3. 이것이 불가능할 경우, (해서는 안 된다그러나 이것이 테스트 목적으로 의도적으로 가짜 호스트 이름이라고 가정하면) 무해한 가상 호스트 이름을 사용하십시오.지적 재산권주소"240.0.0.0", (바라보다반다라미의답변"/dev/null에 해당하는 IP 주소").

새로운 함수를 사용하여 문제가 있는 완료 코드 getent의 출력을 구문 분석합니다.< /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를 동적으로 변경하는 스크립트 작성을 고려하십시오.

관련 정보