Skip to content

Commit

Permalink
Fix displayed ssh port
Browse files Browse the repository at this point in the history
  • Loading branch information
tony-sol committed Apr 8, 2023
1 parent 6bb3c95 commit 4bd013e
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 103 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ Replaces the `#H` format and adds a `#U` format option.

### Usage

- `#H` will be the hostname of your current path. If there is an ssh session opened, the ssh hostname will show instead of the local one.
- `#H` (`#{hostname}`) will be the hostname of your current path. If there is an ssh session opened, the ssh hostname will show instead of the local one.
- `#{hostname_short}` will be the short hostname of your current path (up to the first dot). If there is an ssh session opened, the ssh hostname will show instead of the local one.
- `#U` will show the `whoami` result or the user that logged in an ssh session.
- `#U` (`#{username}`) will show the `whoami` result or the user that logged in an ssh session.
- `#{pane_ssh_port}` if an open ssh session will show the connection port, otherwise it will be empty.
- `#{pane_ssh_connected}` will be set to 1 if the currently selected pane has an active ssh connection. (Useful for `#{?#{pane_ssh_connected},ssh,no-ssh}` which will evaluate to `ssh` if there is an active ssh in the currently selected pane and `no-ssh` otherwise.)
- `#{pane_ssh_connect}` if an open ssh session will show the connection info in `"username@hostname:port"` format, otherwise it will be empty.

Here's the example in `.tmux.conf`:

Expand Down
31 changes: 20 additions & 11 deletions current_pane_hostname.tmux
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,31 @@

CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

interpolation=('\#H' '\#{hostname_short}' '\#U' '\#\{pane_ssh_port\}' '\#\{pane_ssh_connected\}')
script=("#($CURRENT_DIR/scripts/hostname.sh)" "#($CURRENT_DIR/scripts/hostname_short.sh)" "#($CURRENT_DIR/scripts/whoami.sh)" "#($CURRENT_DIR/scripts/port.sh)" "#($CURRENT_DIR/scripts/pane_ssh_connected.sh)")
# Create map placeholders to handle scripts
# to provide one handler for multiple placeholders.
# Use '//' as separator, due to unix limitation in filenames
placeholders_to_scripts=(
"\#U//#($CURRENT_DIR/scripts/user.sh)"
"\#\{username\}//#($CURRENT_DIR/scripts/user.sh)"
"\#H//#($CURRENT_DIR/scripts/host.sh)"
"\#\{hostname\}//#($CURRENT_DIR/scripts/host.sh)"
"\#\{hostname_short\}//#($CURRENT_DIR/scripts/host_short.sh)"
"\#\{pane_ssh_port\}//#($CURRENT_DIR/scripts/port.sh)"
"\#\{pane_ssh_connected\}//#($CURRENT_DIR/scripts/pane_ssh_connected.sh)"
"\#\{pane_ssh_connect\}//#($CURRENT_DIR/scripts/pane_ssh_connect.sh)")


source $CURRENT_DIR/scripts/shared.sh

do_interpolation() {
local interpolated=$1
local j=0

for i in "${interpolation[@]}"; do
local s=${script[$j]}
local interpolated=${interpolated//$i/$s}
((j+=1))
done
echo "$interpolated"
local interpolated=$1
for assignment in ${placeholders_to_scripts[@]}; do
# ${assignment%\/\/*} - remove from // til EOL
# ${assignment#*\/\/} - remove from BOL til //
# ${interpolated//A/B} - replace all occurrences of A in interpolated with B
local interpolated=${interpolated//${assignment%\/\/*}/${assignment#*\/\/}}
done
echo "$interpolated"
}

update_tmux_option() {
Expand Down
2 changes: 1 addition & 1 deletion scripts/whoami.sh → scripts/host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $CURRENT_DIR/shared.sh

main() {
get_info "whoami"
get_info host
}

main
2 changes: 1 addition & 1 deletion scripts/hostname.sh → scripts/host_short.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $CURRENT_DIR/shared.sh

main() {
get_info "hostname"
get_info host_short
}

main
2 changes: 1 addition & 1 deletion scripts/hostname_short.sh → scripts/pane_ssh_connect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $CURRENT_DIR/shared.sh

main() {
get_info "hostname -s"
get_info
}

main
6 changes: 1 addition & 5 deletions scripts/pane_ssh_connected.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $CURRENT_DIR/shared.sh

main() {
if ssh_connected; then
echo 1
else
echo 0
fi
ssh_connected && echo 1 || echo 0
}

main
4 changes: 1 addition & 3 deletions scripts/port.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source $CURRENT_DIR/shared.sh

main() {
if ssh_connected; then
get_info "port"
fi
get_info port
}

main
113 changes: 34 additions & 79 deletions scripts/shared.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ get_tmux_option() {
local option=$1
local default_value=$2
local option_value=$(tmux show-option -gqv "$option")
if [ -z "$option_value" ]; then
echo "$default_value"
else
echo "$option_value"
fi
[[ -z "$option_value" ]] && echo "$default_value" || echo "$option_value"
}

set_tmux_option() {
Expand All @@ -17,87 +13,46 @@ set_tmux_option() {
tmux set-option -gq "$option" "$value"
}

parse_ssh_port() {
# If there is a port get it
local port=$(echo $1|grep -Eo '\-p\s*([0-9]+)'|sed 's/-p\s*//')

if [ -z $port ]; then
local port=22
fi

echo $port
}

get_ssh_user() {
local ssh_user=$(whoami)

for ssh_config in `awk '
$1 == "Host" {
gsub("\\\\.", "\\\\.", $2);
gsub("\\\\*", ".*", $2);
host = $2;
next;
}
$1 == "User" {
$1 = "";
sub( /^[[:space:]]*/, "" );
printf "%s|%s\n", host, $0;
}' .ssh/config`; do
local host_regex=${ssh_config%|*}
local host_user=${ssh_config#*|}
if [[ "$1" =~ $host_regex ]]; then
ssh_user=$host_user
break
fi
done

echo $ssh_user
}

get_remote_info() {
local command=$1

# First get the current pane command pid to get the full command with arguments
local cmd=$({ pgrep -flaP `tmux display-message -p "#{pane_pid}"` ; ps -o command -p `tmux display-message -p "#{pane_pid}"` ; } | xargs -I{} echo {} | grep ssh | sed -E 's/^[0-9]*[[:blank:]]*ssh //')

local port=$(parse_ssh_port "$cmd")

local cmd=$(echo $cmd|sed 's/\-p\s*'"$port"'//g')
local user=$(echo $cmd | awk '{print $NF}'|cut -f1 -d@)
local host=$(echo $cmd | awk '{print $NF}'|cut -f2 -d@)
local command=$1
local pane_pid=$(tmux display-message -p "#{pane_pid}")

if [ $user == $host ]; then
local user=$(get_ssh_user $host)
fi

case "$1" in
"whoami")
echo $user
;;
"hostname")
echo $host
;;
"port")
echo $port
;;
*)
echo "$user@$host:$port"
;;
esac
# First get the current pane command pid to get the full command with arguments
local cmd=$({ pgrep -flaP $pane_pid ; ps -o command -p $pane_pid ; } | xargs -I{} echo {} | grep ssh | sed -E 's/^[0-9]*[[:blank:]]*ssh //')
# Fetch configuration with given cmd
ssh -G $cmd 2>/dev/null | grep -E -e '^host\s' -e '^port\s' -e '^user\s' | sort | cut -f 2 -d ' ' | xargs
}

get_info() {
# If command is ssh do some magic
if ssh_connected; then
echo $(get_remote_info $1)
else
echo $($1)
fi
# If command is ssh, fetch connection info
if ssh_connected; then
read -r host port user <<<$(get_remote_info)
fi
# Return requested info
case "$1" in
"user") # user from ssh info or `whoami`
[[ -z "$user" ]] && whoami || echo "$user"
;;
"host") # host from ssh info or `hostname`
[[ -z "$host" ]] && hostname || echo "$host"
;;
"host_short") # host from ssh info or `hostname -s`
[[ -z "$host" ]] && hostname -s || echo "$host"
;;
"port") # port from ssh info or empty
echo "$port"
;;
*) # user from ssh info + "@host" if host is not empty + ":port" if port is not empty
echo "${user}${host:+@$host}${port:+:$port}"
;;
esac
}

ssh_connected() {
# Get current pane command
local cmd=$(tmux display-message -p "#{pane_current_command}")
local pane_pid=$(tmux display-message -p "#{pane_pid}")

# Get current pane command
local cmd=$(pgrep -flaP $pane_pid)

[ $cmd = "ssh" ] || [ $cmd = "sshpass" ]
[[ $cmd =~ " ssh " ]] || [[ $cmd =~ " sshpass " ]]
}
11 changes: 11 additions & 0 deletions scripts/user.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

source $CURRENT_DIR/shared.sh

main() {
get_info user
}

main

0 comments on commit 4bd013e

Please sign in to comment.