This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

superconfig / tools / ssh-agent-pick / ssh-agent-pick.sh
2.2 kB 66 lines
1#!/usr/bin/env bash 2# Pick one of your live SSH agents (forwarded or local) and print an export line. 3# Usage: eval "$(ssh-agent-pick)" 4 5uid=$(id -u) 6rt=${XDG_RUNTIME_DIR:-/run/user/$uid} 7cands=() 8labels=() 9 10# local agents (configs/tpm2.nix, configs/phonetpm.nix, gpg-agent, gcr). 11# rbw's agent is left out: listing keys blocks on a vault unlock prompt. 12local_socks=( 13 "$rt/ssh-tpm-agent.sock" 14 "$rt/phonetpm/agent.sock" 15 "$rt/gnupg/S.gpg-agent.ssh" 16 "$rt/gcr/ssh" 17) 18 19# newest first: sshd creates a forwarded socket when the connection is established 20while IFS= read -r -d '' line; do 21 sock=${line#* } 22 [ -S "$sock" ] || continue 23 [ "$(stat -c %u "$sock")" = "$uid" ] || continue 24 rc=0 25 # timeout: an agent waiting on an unlock prompt must not hang the picker 26 keys=$(SSH_AUTH_SOCK=$sock timeout 3 ssh-add -l 2>/dev/null) || rc=$? 27 [ "$rc" -le 1 ] || continue # 2 = cannot connect (stale), 124 = timed out 28 if [ "$rc" -eq 1 ]; then 29 keys="(no identities)" 30 else 31 keys=$(printf '%s\n' "$keys" | awk '{ $1 = $2 = ""; $NF = ""; sub(/^ +/, ""); sub(/ +$/, ""); print }' | paste -sd, -) 32 fi 33 since=$(date -d "@${line%% *}" '+%F %T') 34 case $sock in 35 "$rt"/*) kind=local ;; 36 *) kind=forwarded ;; 37 esac 38 cands+=("$sock") 39 labels+=("$since $kind $keys $sock") 40done < <({ 41 # errexit applies in here: a failing find must not skip the next one 42 find /tmp/ssh-* "$HOME/.ssh/agent" -maxdepth 1 -type s \( -name 'agent.*' -o -name '*.sshd.*' \) -printf '%T@ %p\0' || true 43 find "${local_socks[@]}" -maxdepth 0 -type s -printf '%T@ %p\0' || true 44} 2>/dev/null | sort -zrn) 45 46if [ ${#cands[@]} -eq 0 ]; then 47 echo "ssh-agent-pick: no live agent found" >&2 48 exit 1 49fi 50 51if [ ${#cands[@]} -eq 1 ]; then 52 choice=${cands[0]} 53elif [ -t 2 ]; then 54 sel=$(printf '%s\n' "${labels[@]}" | fzf --height=~10 --reverse --prompt='agent> ') || exit 1 55 choice=${sel##* } 56else 57 PS3='agent> ' 58 select _ in "${labels[@]}"; do 59 [ -n "${REPLY:-}" ] && [ "$REPLY" -ge 1 ] 2>/dev/null && [ "$REPLY" -le ${#cands[@]} ] || continue 60 choice=${cands[REPLY - 1]} 61 break 62 done 63fi 64 65[ -n "${choice:-}" ] || exit 1 66printf "export SSH_AUTH_SOCK='%s'\n" "$choice"