Como editar a conclusão do comando para o ssh no zsh?

11

Gostaria de configurar a conclusão do comando no zsh para exibir nomes de host depois de digitar

ssh [TAB]

pegando os nomes do meu arquivo .ssh / config (e preferencialmente de known_hosts e / etc / hosts e qualquer outro lugar que faça sentido) e apresentando uma única lista.

Ele faz parte disso atualmente, mas

  1. não usa .ssh / config em todos
  2. requer primeiro um nome de usuário, mesmo que o uso de .ssh / config torne desnecessário digitar nomes de usuário
  3. apresenta várias listas (provavelmente uma de known_hosts e outra de / etc / hosts, mas eu não verifiquei isso)

Portanto, quero incluir nomes de usuários conhecidos, bem como nomes de hosts conhecidos na lista (de preferência, única) depois de digitar ssh [TAB]

(Eu estou chegando aqui antes do Google porque 1) isso resultará em uma resposta armazenada aqui e 2) é provavelmente mais eficiente. Se ninguém mais responder, eu procurarei a resposta.)

    
por iconoclast 13.08.2010 / 22:47

4 respostas

15

Aqui está a parte relevante do meu .zshrc . Ele não mudou desde 2002, portanto, posso escrevê-lo de maneira diferente hoje, mas ainda funciona para completar os nomes de host de ~/.ssh/config e ~/.ssh/known_hosts (se HashKnownHosts estiver desativado - não existia naqueles dias).

h=()
if [[ -r ~/.ssh/config ]]; then
  h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*})
fi
if [[ -r ~/.ssh/known_hosts ]]; then
  h=($h ${${${(f)"$(cat ~/.ssh/known_hosts{,2} || true)"}%%\ *}%%,*}) 2>/dev/null
fi
if [[ $#h -gt 0 ]]; then
  zstyle ':completion:*:ssh:*' hosts $h
  zstyle ':completion:*:slogin:*' hosts $h
fi
    
por 14.08.2010 / 11:11
1

A função que fornece ssh completion está localizada em /usr/share/zsh/functions/Completion/Unix/_ssh no meu sistema.

Veja também man zshcompsys para documentação (especialmente faça uma pesquisa em "host" que aparece em vários lugares e "ssh" que aparece em alguns lugares).

Pode ser possível que a adição de um comando zstyle ao seu ~/.zshrc faça o que você está procurando sem ter que modificar a função de conclusão.

    
por 13.08.2010 / 23:08
1

Eu faço isso usando uma lista de todos os hosts em um determinado domínio usando dig. Você pode substituir a função abaixo pelo sistema de pesquisa desejado, incluindo o arquivo de hosts ou uma lista estática:

function complete_host_from_zone () {
    reply=('dig axfr ouraynet.com @ns1.ouraynet.com | grep -e '^[a-z]' | cut -d\. -f1')
}
compctl -x 'p[1]' -K complete_host_from_zone -- ssh

Nota: O código acima pode não substituir totalmente o sistema completo do comando ssh na sua configuração. Se você tiver problemas com isso, tente alterar o comando "ssh" para algum outro comando aleatório como "mycompletetest" e veja se a conclusão funciona para isso.

Observe também que isso faz a transferência da zona dns a cada conclusão! Se você usar muito isso ou em um domínio bastante estático, faria sentido fazer a pesquisa e salvar o resultado, então, em sua função de pesquisa, basta definir reply = zone_result.

    
por 19.10.2010 / 13:03
0

Gosto de manter meu arquivo known_hosts com hash e prefiro não ativar HashKnownHosts . Eu descobri que semear o que o @Gilles tem com o que já está na minha história tem sido bastante eficaz para as minhas necessidades.

h=($(echo $(history | awk '{print $4 " " $5 "\n"}' | grep 'ssh ' | awk '{print $2}' | sort -u)))
if [[ -r ~/.ssh/config ]]; then
  h=($h ${${${(@M)${(f)"$(cat ~/.ssh/config)"}:#Host *}#Host }:#*[*?]*})
fi
if [[ -r ~/.ssh/known_hosts ]]; then
   h=($h ${${${(f)"$(cat ~/.ssh/known_hosts{,2} || true)"}%%\ *}%%,*}) 2>/dev/null
fi
if [[ $#h -gt 0 ]]; then
  zstyle ':completion:*:ssh:*' hosts $h
  zstyle ':completion:*:slogin:*' hosts $h
fi

Além disso, FWIW, isso é o que eu usei para o Bash:

# SSH Autocompletion
complete -W "
  $(echo $(grep '^\s*ssh ' ~/.bash_history | sort -u | sed 's/^ssh //' | awk '{print $1}'))
  $(echo $(history | awk '{print $2 " " $3}' | grep 'ssh ' | awk '{print $2}' | sort -u))
  $(sed 's/#.*//;' ~/.ssh/config | awk ' /^Host (.+)$/ {$1 = "";print tolower($0)}')
" ssh
    
por 29.01.2015 / 03:41