1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#!/usr/bin/env perl
#
# Author: Guillermo Ramos <gramos@gramos.me>
# SPDX-License-Identifier: BSD-3-Clause
#
# Minimalistic SSH connector which uses FZF and the SSH config 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. It also supports passwords
# stored in `pass`, using the wrappers "passh" (provided in this repo" and
# "sshpass".
#
################################################################################
use strict;
use warnings;
my @hosts;
my $remote_session_name = $ENV{SSF_REMOTE_USER} || $ENV{USER};
foreach my $cfgfile (glob "$ENV{HOME}/.ssh/config.d/*") {
open(my $ssh_config, '<', $cfgfile) or die "nope";
my @line_hosts;
while (my $line = <$ssh_config>) {
my ($key, $value);
if ($line =~ /^\s*([A-Z][a-zA-Z]+)\s+([^#\n]+)/) {
$key = $1;
$value = $2;
}
next unless defined $key;
if ($key eq 'Host') {
@line_hosts = map { { _pat => $_ } } (split /\s/, $value);
push @hosts, @line_hosts;
} elsif ($key eq 'Match') {
@line_hosts = ();
} else {
$_->{$key} = $value foreach (@line_hosts);
}
}
}
my @hosts_no_wild = grep { not $_ =~ /\*/ } (map { $_->{_pat} } @hosts);
my $newlined_hosts = join "\n", sort @hosts_no_wild;
my $fzf_cmd = 'fzf';
if (exists $ENV{TMUX}) {
if (`which fzf-tmux`) {
$fzf_cmd = 'fzf-tmux';
}
}
my $prompt = @ARGV ? "$ARGV[0] " : "";
my $selection = `
echo -n "$newlined_hosts" |
$fzf_cmd -1 --print-query -q "$prompt"
`;
my $retval = $? >> 8;
my @lines = split "\n", $selection;
my $hostname;
if ($retval == 0) {
# 0: normal exit; a host has been selected
$hostname = $lines[1];
} elsif ($retval == 1) {
# 1: no match; pick user input
$hostname = $lines[0];
} else {
# either 2 (error) or 130 (interrupted wth C-c or ESC)
exit $retval;
}
$hostname =~ s/^\s+|\s+$//g; # Trim whitespace
# Save the final command to the shell history...?
#`print -s "ssh $hostname"`;
`which sshpass && which passh`;
my @cmd = ($? eq 0 ? 'passh' : 'ssh', $hostname, '-t', "sh -c \"tmux new -As $remote_session_name\"");
if (exists $ENV{TMUX}) {
`tmux rename-window $hostname`;
system 'passh', $hostname, '-t', "sh -c \"tmux new -As $remote_session_name\"";
`tmux rename-window '[$hostname]'`;
} else {
exec 'passh', $hostname, '-t', "sh -c \"tmux new -As $remote_session_name\"";
}
|