Posts tagged ‘git’

Using zsh as default shell is perfect. Using grml-zsh stuff to configure it, even better. Using XTaran’s config, way better. Using your own config, invaluable. Now, there is one thing that always bothered me: having all hosts I usually deal with in my ~/.ssh/config in order to have tab completion (and short names). I wanted to improve the situation and was kindly pointed in a different direction by Myon, namely to just use the ~/.ssh/known_hosts for tab completion. How about that?

I started playing around with the config and, as it turns out, Axel already has something ready. Unfortunately, it didn’t fulfill all my needs yet. That is because I have multiple known_hosts files. Martin already filed a bug to have ssh read ~/.ssh/known_hosts.d/* but that isn’t resolved yet either, even though upstream is aware of it. I thus had to point tab completion and ssh to multiple files by hand. But that’s not too bad for now. Let’s have a look:

Host *
        HashKnownHosts no

Host *.your-work.com
        User that-is-what-they-call-me-at-work
        UserKnownHostsFile ~/.ssh/known_hosts.work

Host *.debian.org
        UserKnownHostsFile ~/.ssh/known_hosts.debian

What am I doing? Well, we need to deactivate the hashing of known hosts. Otherwise your known_hosts files aren’t readable as needed. Then you define your known_hosts files for the domains you care about. Pretty straight forward.

Now, how about tab completion in zsh? Well, easy part actually:

[ -f ~/.ssh/config ] && : ${(A)ssh_config_hosts:=${${${${(@M)${(f)"$(<~/.ssh/config)"}:#Host *}#Host }:#*\**}:#*\?*}} [ -f ~/.ssh/known_hosts ] && : ${(A)ssh_known_hosts:=${${${(f)"$(<$HOME/.ssh/known_hosts)"}%%\ *}%%,*}} [ -f ~/.ssh/known_hosts.work ] && : ${(A)ssh_known_hosts_work:=${${${(f)"$(<$HOME/.ssh/known_hosts.work)"}%%\ *}%%,*}} [ -f ~/.ssh/known_hosts.debian ] && : ${(A)ssh_known_hosts_debian:=${${${(f)"$(<$HOME/.ssh/known_hosts.debian)"}%%\ *}%%,*}} zstyle ':completion:*:hosts' hosts $ssh_config_hosts $ssh_known_hosts $ssh_known_hosts_work $ssh_known_hosts_debian

What's here? We read and parse your ~/.ssh/config for configured hosts, then we parse all your known_hosts files which are for me: ~/.ssh/known_hosts, ~/.ssh/known_hosts.work, and ~/.ssh/known_hosts.debian. And lastly, all is added to zsh completion for hosts. That actually works. :)

Axel, that makes a diff for you looking like this:

diff --git a/zsh.d/70-completion b/zsh.d/70-completion
index e92e068..5abf5cc 100644
--- a/zsh.d/70-completion
+++ b/zsh.d/70-completion
@@ -8,6 +8,8 @@

[ -f ~/.ssh/config ] && : ${(A)ssh_config_hosts:=${${${${(@M)${(f)"$(<~/.ssh/config)"}:#Host *}#Host }:#*\**}:#*\?*}} [ -f ~/.ssh/known_hosts ] && : ${(A)ssh_known_hosts:=${${${(f)"$(<$HOME/.ssh/known_hosts)"}%%\ *}%%,*}} +[ -f ~/.ssh/known_hosts.work ] && : ${(A)ssh_known_hosts_work:=${${${(f)"$(<$HOME/.ssh/known_hosts.work)"}%%\ *}%%,*}} +[ -f ~/.ssh/known_hosts.debian ] && : ${(A)ssh_known_hosts_debian:=${${${(f)"$(<$HOME/.ssh/known_hosts.debian)"}%%\ *}%%,*}} -zstyle ':completion:*:*:*' hosts $ssh_config_hosts $ssh_known_hosts +zstyle ':completion:*:hosts' hosts $ssh_config_hosts $ssh_known_hosts $ssh_known_hosts_work $ssh_known_hosts_debian

Care to merge?

Oh, and before I forget... Of course you don't need to check each and every host by yourself. Debian provides ssh keys for all hosts on master. Just do a

scp master.debian.org:/etc/ssh/ssh_known_hosts ~/.ssh/known_hosts.debian

and I'm sure, your security aware employer has such a file for you as well. Doesn't he? ;)