diff options
-rwxr-xr-x | ssf | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -0,0 +1,78 @@ +#!/usr/bin/env perl +# +# Author: Guillermo Ramos <gramos@gramos.me> +# SPDX-License-Identifier: BSD-3-Clause +# +# Minimalistic SSH connector which uses FZF, the SSH config and the known_hosts file +# to show a reasonable list of machines to connect to. Then it starts or attaches to +# a remote tmux session named as the current user. +# +################################################################################ + +use strict; +use warnings; + +my @hosts; +my %aliases; + +open(my $ssh_config, '<', "$ENV{HOME}/.ssh/config") or die "nope"; +while (my $line = <$ssh_config>) { + if ($line =~ /^Host ([^#\n]+)(?: # (.*))?$/) { + push @hosts, split(/ /, $1); + if (defined $2) { + $aliases{$_} = $1 foreach split / /, $2; + } + } +} + +my $egrep_regex = join "|", grep { $_ =~ /\*/ } @hosts; +$egrep_regex =~ s/\./\\./g; +$egrep_regex =~ s/\*/.*/g; + +my $known_hosts = ` + egrep '$egrep_regex' ~/.ssh/known_hosts | + cut -f1 -d" " | + sort -u +`; +my $hosts_no_wild = join "\n", grep { not $_ =~ /\*/ } @hosts; +my $aliases = join "\n", keys %aliases; +my $prompt = @ARGV ? "@ARGV " : ""; +my $selection = ` + echo -n "${known_hosts}$aliases\n$hosts_no_wild" | + fzf -1 --print-query -q "$prompt" +`; +my $retval = $? >> 8; +my @lines = split "\n", $selection; + +my $hostname; +if ($retval == 0) { + $hostname = $lines[1]; +} elsif ($retval == 1) { + $hostname = $lines[0]; +} else { + exit $retval; +} + +$hostname =~ s/^\s+|\s+$//g; # Trim whitespace +my $host = $aliases{$hostname} || $hostname; # Resolve alias + +# Save the final command to the shell history...? +#`print -s "ssh $host"`; + +# Special behavior for tmux +if (exists $ENV{TMUX}) { + my $window_id = `tmux list-windows -F '#{window_index}' -f '#{==:#{window_name},$hostname}'`; + $window_id =~ s/^\s+|\s+$//g; # Trim whitespace + if ($window_id ne '') { + # The window exists; select it instead + `tmux select-window -t $window_id`; + } else { + # The window does not exist; make the connection in the current one + # and it to the machine we're connecting to + `tmux rename-window $hostname`; + system 'ssh', '-t', $host, "sh -c \"tmux new -As $ENV{USER}\""; + `tmux rename-window '!$hostname'`; + } +} else { + exec 'ssh', '-t', $host, "sh -c \"tmux new -As $ENV{USER}\""; +} |