[zsh] Make ssh loading across platform more robust
This commit is contained in:
130
bin/.local/bin/ssh-agent-doctor
Executable file
130
bin/.local/bin/ssh-agent-doctor
Executable file
@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
ssh-agent-doctor: diagnose and select the best SSH_AUTH_SOCK.
|
||||
|
||||
Usage:
|
||||
ssh-agent-doctor # human-readable report
|
||||
ssh-agent-doctor --export # print: export SSH_AUTH_SOCK='...'
|
||||
ssh-agent-doctor --json # minimal JSON-ish output (no jq required)
|
||||
|
||||
Exit codes:
|
||||
0 OK (agent reachable)
|
||||
1 Socket found but agent has no identities (reachable)
|
||||
2 No usable socket found OR cannot connect to agent
|
||||
EOF
|
||||
}
|
||||
|
||||
mode="report"
|
||||
case "${1:-}" in
|
||||
--export) mode="export" ;;
|
||||
--json) mode="json" ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
"") ;;
|
||||
*) echo "Unknown arg: $1" >&2; usage; exit 2 ;;
|
||||
esac
|
||||
|
||||
os="$(uname -s 2>/dev/null || echo unknown)"
|
||||
uid="$(id -u)"
|
||||
user="$(id -un 2>/dev/null || echo unknown)"
|
||||
home="${HOME:-/}"
|
||||
|
||||
linux_sock="/run/user/${uid}/ssh-agent.socket"
|
||||
darwin_sock="${home}/.ssh/agent.sock"
|
||||
env_sock="${SSH_AUTH_SOCK:-}"
|
||||
|
||||
is_sock() { [[ -n "${1:-}" && -S "$1" ]]; }
|
||||
|
||||
pick_sock=""
|
||||
pick_reason=""
|
||||
|
||||
if is_sock "$linux_sock"; then
|
||||
pick_sock="$linux_sock"
|
||||
pick_reason="linux_systemd_default"
|
||||
elif is_sock "$darwin_sock"; then
|
||||
pick_sock="$darwin_sock"
|
||||
pick_reason="darwin_launchd_default"
|
||||
elif is_sock "$env_sock"; then
|
||||
pick_sock="$env_sock"
|
||||
pick_reason="existing_env"
|
||||
fi
|
||||
|
||||
check_agent() {
|
||||
local sock="$1"
|
||||
SSH_AUTH_SOCK="$sock" ssh-add -l >/dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
|
||||
if [[ "$mode" == "export" ]]; then
|
||||
if [[ -z "$pick_sock" ]]; then
|
||||
echo "echo 'ERROR: No ssh-agent socket found.' >&2"
|
||||
echo "return 2 2>/dev/null || exit 2"
|
||||
exit 0
|
||||
fi
|
||||
printf "export SSH_AUTH_SOCK='%s'\n" "$pick_sock"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$mode" == "json" ]]; then
|
||||
if [[ -z "$pick_sock" ]]; then
|
||||
cat <<EOF
|
||||
{"ok":false,"user":"$user","uid":$uid,"os":"$os","picked":"","reason":"","error":"no_socket","candidates":{"linux":"$linux_sock","darwin":"$darwin_sock","env":"$env_sock"}}
|
||||
EOF
|
||||
exit 2
|
||||
fi
|
||||
|
||||
rc=0
|
||||
check_agent "$pick_sock" || rc=$?
|
||||
# ssh-add -l exit codes: 0 has keys, 1 no keys, 2 cannot connect
|
||||
ok=false
|
||||
status="unknown"
|
||||
if [[ $rc -eq 0 ]]; then ok=true; status="has_identities"; fi
|
||||
if [[ $rc -eq 1 ]]; then ok=true; status="no_identities"; fi
|
||||
if [[ $rc -eq 2 ]]; then ok=false; status="cannot_connect"; fi
|
||||
|
||||
cat <<EOF
|
||||
{"ok":$ok,"user":"$user","uid":$uid,"os":"$os","picked":"$pick_sock","reason":"$pick_reason","ssh_add_l_exit":$rc,"status":"$status","candidates":{"linux":"$linux_sock","darwin":"$darwin_sock","env":"$env_sock"}}
|
||||
EOF
|
||||
exit $rc
|
||||
fi
|
||||
|
||||
# Human report mode
|
||||
echo "ssh-agent-doctor"
|
||||
echo " user: $user (uid $uid)"
|
||||
echo " os: $os"
|
||||
echo
|
||||
echo "Candidates:"
|
||||
printf " linux systemd: %s %s\n" "$linux_sock" "$(is_sock "$linux_sock" && echo '[socket]' || echo '[missing]')"
|
||||
printf " macOS launchd: %s %s\n" "$darwin_sock" "$(is_sock "$darwin_sock" && echo '[socket]' || echo '[missing]')"
|
||||
printf " env SSH_AUTH_SOCK: %s %s\n" "${env_sock:-<unset>}" "$(is_sock "$env_sock" && echo '[socket]' || echo '[not socket]')"
|
||||
echo
|
||||
|
||||
if [[ -z "$pick_sock" ]]; then
|
||||
echo "Result: ❌ No usable SSH agent socket found."
|
||||
echo "Hint: start your agent (systemd user on Linux, launchd agent on macOS) and re-run."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "Picked:"
|
||||
echo " SSH_AUTH_SOCK=$pick_sock"
|
||||
echo " reason=$pick_reason"
|
||||
echo
|
||||
|
||||
rc=0
|
||||
check_agent "$pick_sock" || rc=$?
|
||||
|
||||
if [[ $rc -eq 0 ]]; then
|
||||
echo "Agent check: ✅ reachable, has identities"
|
||||
SSH_AUTH_SOCK="$pick_sock" ssh-add -l || true
|
||||
exit 0
|
||||
elif [[ $rc -eq 1 ]]; then
|
||||
echo "Agent check: ✅ reachable, but has no identities loaded"
|
||||
echo "Next: run your pass-based loader (load_keys)."
|
||||
exit 1
|
||||
else
|
||||
echo "Agent check: ❌ cannot connect to agent via that socket"
|
||||
echo "This usually means the socket is stale or the agent died."
|
||||
exit 2
|
||||
fi
|
||||
32
bin/.local/bin/ssh-agent-env
Executable file
32
bin/.local/bin/ssh-agent-env
Executable file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
uid="$(id -u)"
|
||||
|
||||
linux_sock="/run/user/${uid}/ssh-agent.socket"
|
||||
darwin_sock="${HOME}/.ssh/agent.sock"
|
||||
|
||||
pick_sock=""
|
||||
|
||||
# Prefer Linux systemd socket if present
|
||||
if [[ -S "$linux_sock" ]]; then
|
||||
pick_sock="$linux_sock"
|
||||
elif [[ -S "$darwin_sock" ]]; then
|
||||
pick_sock="$darwin_sock"
|
||||
else
|
||||
# Fall back to existing env if it's a socket
|
||||
if [[ -n "${SSH_AUTH_SOCK:-}" && -S "${SSH_AUTH_SOCK}" ]]; then
|
||||
pick_sock="$SSH_AUTH_SOCK"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "$pick_sock" ]]; then
|
||||
echo "echo 'ERROR: No ssh-agent socket found.' >&2"
|
||||
echo "echo 'Tried: $linux_sock and $darwin_sock' >&2"
|
||||
echo "return 2 2>/dev/null || exit 2"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
export SSH_AUTH_SOCK='$pick_sock'
|
||||
EOF
|
||||
Reference in New Issue
Block a user