feat: added ssh launcher
This commit is contained in:
parent
440534919c
commit
dcd6982fd6
133
ssh.sh
Executable file
133
ssh.sh
Executable file
@ -0,0 +1,133 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
KNOWN_CRED_FILE="$HOME/.ssh/known_creds"
|
||||||
|
KNOWN_HOSTS_FILE="$HOME/.ssh/known_hosts"
|
||||||
|
|
||||||
|
# === 1. Load credentials from file ===
|
||||||
|
TMP_CREDS=$(mktemp)
|
||||||
|
trap 'rm -f "$TMP_CREDS"' EXIT
|
||||||
|
if [ -f "$KNOWN_CRED_FILE" ]; then
|
||||||
|
cp "$KNOWN_CRED_FILE" "$TMP_CREDS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === 2. Parse known_hosts (deduped) ===
|
||||||
|
TMP_HOSTS=$(mktemp)
|
||||||
|
trap 'rm -f "$TMP_CREDS" "$TMP_HOSTS"' EXIT
|
||||||
|
if [ -f "$KNOWN_HOSTS_FILE" ]; then
|
||||||
|
grep -v '^[[:space:]]*#' "$KNOWN_HOSTS_FILE" | \
|
||||||
|
awk '
|
||||||
|
{
|
||||||
|
split($1, parts, ",")
|
||||||
|
for (i in parts) {
|
||||||
|
h = parts[i]
|
||||||
|
gsub(/[][]/, "", h)
|
||||||
|
port = 22
|
||||||
|
if (match(h, /:[0-9]+$/)) {
|
||||||
|
port = substr(h, RSTART+1)
|
||||||
|
h = substr(h, 1, RSTART-1)
|
||||||
|
}
|
||||||
|
key = h ":" port
|
||||||
|
if (!(key in seen)) { seen[key] = 1; print h "|" port }
|
||||||
|
}
|
||||||
|
}' > "$TMP_HOSTS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if hosts found
|
||||||
|
if [ ! -s "$TMP_HOSTS" ]; then
|
||||||
|
echo "⚠️ No hosts in ~/.ssh/known_hosts. Run 'ssh user@host' first." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === 3. Build menu + store full credentials ===
|
||||||
|
hosts_data=()
|
||||||
|
echo "📋 Available hosts:"
|
||||||
|
i=1
|
||||||
|
while IFS='|' read -r host port; do
|
||||||
|
user=""
|
||||||
|
pass=""
|
||||||
|
# Safely extract credentials (avoid grep failure)
|
||||||
|
match=$(grep "^$host|" "$TMP_CREDS" 2>/dev/null | head -n1) || true
|
||||||
|
if [ -n "$match" ]; then
|
||||||
|
IFS='|' read -r _ user _ pass <<< "$match"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine mode: 1 = auto-pass, 0 = manual
|
||||||
|
mode=0
|
||||||
|
if [ -n "$user" ] && [ -n "$pass" ]; then
|
||||||
|
mode=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
hosts_data+=("$host|$port|$user|$pass|$mode")
|
||||||
|
if [ "$mode" -eq 1 ]; then
|
||||||
|
echo "$i) $host ($port) — $user (auto-pass)"
|
||||||
|
else
|
||||||
|
echo "$i) $host ($port)"
|
||||||
|
fi
|
||||||
|
i=$((i + 1))
|
||||||
|
done < "$TMP_HOSTS"
|
||||||
|
echo "$i) Cancel"
|
||||||
|
|
||||||
|
# === 4. Prompt for host ===
|
||||||
|
PS3="Select: "
|
||||||
|
while true; do
|
||||||
|
read -r choice || exit 0
|
||||||
|
if [ "$choice" = "$i" ]; then
|
||||||
|
echo "Cancelled."
|
||||||
|
exit 0
|
||||||
|
elif [ "$choice" -ge 1 ] && [ "$choice" -lt "$i" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo "Invalid. Try again:"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Extract selected host/credentials
|
||||||
|
item="${hosts_data[$((choice-1))]}"
|
||||||
|
IFS='|' read -r host port user pass mode <<< "$item"
|
||||||
|
|
||||||
|
# === 5. Get credentials if not auto-pass ===
|
||||||
|
if [ "$mode" -eq 0 ]; then
|
||||||
|
read -rp "Username [$USER]: " user
|
||||||
|
user="${user:-$USER}"
|
||||||
|
|
||||||
|
stty -echo 2>/dev/null || true
|
||||||
|
read -rp "Password: " pass
|
||||||
|
stty echo 2>/dev/null || true
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Save if requested
|
||||||
|
read -rp "Save credentials? [y/N]: " save
|
||||||
|
if [ "$save" = "y" ] || [ "$save" = "Y" ]; then
|
||||||
|
if [ -f "$KNOWN_CRED_FILE" ]; then
|
||||||
|
grep -v "^$host|" "$KNOWN_CRED_FILE" > "${KNOWN_CRED_FILE}.tmp" || true
|
||||||
|
mv "${KNOWN_CRED_FILE}.tmp" "$KNOWN_CRED_FILE"
|
||||||
|
fi
|
||||||
|
echo "$host|$user|$port|$pass" >> "$KNOWN_CRED_FILE"
|
||||||
|
chmod 600 "$KNOWN_CRED_FILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === 6. Launch SSH — reuse existing window/pane ===
|
||||||
|
# Ensure sshpass is available
|
||||||
|
if ! command -v sshpass >/dev/null 2>&1; then
|
||||||
|
echo "⚠️ Install sshpass: brew install hudochenkov/sshpass/sshpass"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get WezTerm pane ID if available
|
||||||
|
pane_id=""
|
||||||
|
if osascript -e 'application "WezTerm" is running' >/dev/null 2>&1; then
|
||||||
|
pane_id=$(wezterm cli list-panes -q 2>/dev/null | head -n1 | cut -d' ' -f1) || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create safe command with quoted password
|
||||||
|
safe_cmd=$(printf 'sshpass -p %q ssh -p %s %s@%s' "$pass" "$port" "$user" "$host")
|
||||||
|
|
||||||
|
# Reuse pane or spawn new tab
|
||||||
|
if [ -n "$pane_id" ]; then
|
||||||
|
wezterm cli send-text --pane "$pane_id" "$safe_cmd\n"
|
||||||
|
else
|
||||||
|
# Fallback: spawn new tab in existing window
|
||||||
|
wezterm cli spawn --cwd "$HOME" -- sh -c "$safe_cmd"
|
||||||
|
fi
|
||||||
Loading…
x
Reference in New Issue
Block a user