-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
tmux-ssh-split.sh
executable file
·149 lines (128 loc) · 3.13 KB
/
tmux-ssh-split.sh
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/env bash
usage() {
echo "Usage: $(basename "$0") ARGS"
echo
echo "Arguments:"
echo " -v|-h Vertical or horizontal split"
echo " --fail Error out if there is no SSH session in the current pane"
echo " --verbose Display a message when spawning a new SSH session/pane"
echo " --no-shell Don't spawn a shell after the SSH command"
echo " -c DIR Set start directory for pane"
}
get_current_pane_info() {
tmux display -p '#{pane_id} #{pane_pid}'
}
get_current_pane_id() {
get_current_pane_info | awk '{ print $1 }'
}
get_pane_pid_from_pane_id() {
tmux list-panes -F "#{pane_id} #{pane_pid}" | awk "/^$1 / { print \$2}"
}
# $1 is optional, disable 2120
# shellcheck disable=2120
get_ssh_command() {
local pane_id
local pane_pid
pane_id="${1:-$(get_current_pane_id)}"
pane_pid="$(get_pane_pid_from_pane_id "$pane_id")"
if [[ -z "$pane_pid" ]]
then
echo "Could not determine pane PID" >&2
return 3
fi
for child_pid in $(pgrep -P "${pane_pid}")
do
child_cmd="$(ps -o command= "$child_pid")"
if [[ "$child_cmd" =~ ^(auto)?ssh.* ]]
then
echo "$child_cmd"
return
fi
done
return 1
}
get_remote_cwd() {
# PROBABLY WON'T EVER WORK
# To get the current paths on the remote server one can run the following:
# for pid in $(pgrep -P "$(pgrep -a sshd | grep -- "${SSH_TTY##/dev/}" | awk '{ print $1; exit }')"); do readlink -f /proc/$pid/cwd; done
echo "Not implemented yet!" >&2
return 1
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]
then
SPLIT_ARGS=()
while [[ -n "$*" ]]
do
case "$1" in
help|h|--help)
usage
exit 0
;;
-h|-v)
SPLIT_ARGS+=("$1")
shift
;;
-c)
if [[ -z "$2" ]]
then
echo "Missing start directory" >&2
usage >&2
exit 2
fi
# Only set start dir if it still exists
if [[ -d "$2" ]]
then
SPLIT_ARGS+=(-c "$2")
fi
shift 2
;;
--fail)
FAIL=1
shift
;;
--no-shell|-n)
NO_SHELL=1
shift
;;
--verbose|-V)
VERBOSE=1
shift
;;
-*)
usage >&2
exit 2
;;
esac
done
ssh_command="$(get_ssh_command)"
if [[ -z "$ssh_command" ]]
then
if [[ -n "$FAIL" ]]
then
tmux display "Error: current pane seems to not be running SSH..."
echo "Could not determine SSH command" >&2
else
tmux split "${SPLIT_ARGS[@]}"
fi
exit 0
fi
start_cmd="$ssh_command"
if [[ -z "$NO_SHELL" ]]
then
default_shell="$(tmux show-option -gqv "default-shell")"
if [[ -z "$default_shell" ]]
then
# Fall back to sh
default_shell="$(command -v sh)"
fi
# Open default shell on exit (SSH timeout, Ctrl-C etc.)
start_cmd="trap ${default_shell} EXIT INT; $start_cmd"
fi
if [[ -n "$VERBOSE" ]]
then
start_cmd="echo '🧙👉 Running \"$ssh_command\"'; $start_cmd"
fi
# Spawn a new shell after the ssh command to keep the pane alive
tmux split "${SPLIT_ARGS[@]}" "$start_cmd"
fi
# vim: set ft=bash et ts=2 sw=2 :