Posts tagged ‘zsh’

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? ;)

Been playing with that thought for a while now, finally got to rebuilding it for lenny, now I’m using it… tmux is the new screen. To have fun already I read a few short introductions and got myself a few suggestions for a proper .tmux.conf. So, for root I have this one now:

# Copy mode
unbind [
bind Escape copy-mode

# Use Vi mode
setw -g mode-keys vi

# Make mouse useful in copy mode
setw -g mode-mouse on

# More straight forward key bindings for splitting
unbind %
bind | split-window -h
bind h split-window -h
unbind '"'
bind - split-window -v
bind v split-window -v

# History
set -g history-limit 4000

# Terminal emulator window title
set -g set-titles on
set -g set-titles-string '#S:#I.#P #W'

# Status Bar
set -g status-bg black
set -g status-fg white
set -g status-interval 1
set -g status-left '#[fg=green]#H#[default]'
# no line break here, it's just to long for my blog layout!
set -g status-right '#[fg=yellow]#(cut -d " " -f 1-4 /proc/loadavg)#[default] #[fg=cyan,bold]%Y-%m-%d %H:%M:%S#[default]'

# Notifying if other windows has activities
setw -g monitor-activity on
set -g visual-activity on

# Highlighting the active window in status bar
setw -g window-status-current-bg red

# Clock
setw -g clock-mode-colour green
setw -g clock-mode-style 24

# Create a default session
new -n htop -d htop
setw -t htop monitor-activity off
neww -n aptitude -d aptitude
neww -d

Then I added a new alias to my user’s zsh config:

alias root='su -c "tmux attach"'

Why ‘tmux attach’? Because tmux would start a new session which I don’t want it to. The config already starts a session which we can immediately attach to. Also, when such session was started I can attach to it as a user with the very same command over and over again. That makes it pretty handy as I always have htop, aptitude and a free shell available in a nice tmux session. Great. How did I live until now? ;-)