Last active
February 17, 2023 21:46
-
-
Save cppcooper/7a0467b5cdb3fb3ba468144be3a76a0c to your computer and use it in GitHub Desktop.
Attach ssh-agent to multiple terminals
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/bash | |
windows() { [[ -n "$WINDIR" ]]; } | |
if ! windows; then | |
lock="/tmp/.lock-sshbash" | |
exec 3>$lock | |
flock --timeout 300 3 || exit 1 | |
fi | |
get-agents() { | |
if windows; then | |
tasklist //V | grep ssh-agent | grep $(whoami) | |
else | |
ps x | grep ssh-agent | grep -v grep | |
fi | |
} | |
get-pid() { | |
if windows; then | |
awk '{print $2}' | |
else | |
awk '{print $1}' | |
fi | |
} | |
kill-ssh-agent(){ | |
for pid in $(get-agents | get-pid) | |
do | |
if windows; then | |
taskkill //F //PID $pid | |
else | |
kill $pid | |
fi | |
done | |
} | |
print-ssh-connection-info(){ | |
echo $SSH_AUTH_SOCK | |
if windows;then | |
echo Agent winpid $(ps | grep $SSH_AGENT_PID | grep -v grep | awk '{print $4}') | |
fi | |
echo Agent pid $SSH_AGENT_PID | |
echo Active keys | |
echo ----------- | |
ssh-add -l | |
} | |
connect-ssh-agent(){ | |
if [ -f ~/.ssh/agent.sh ] | |
then | |
debug_ "running agent.sh" | |
. ~/.ssh/agent.sh 2>&1 >/dev/null | |
#print-ssh-connection-info | |
else | |
debug_ "agent.sh doesn't exist" | |
touch ~/.ssh/agent.sh | |
#echo "Critical Error: ~/.ssh/agent.sh does not exist" | |
fi | |
} | |
start-ssh-agent(){ | |
debug_ "start_ssh_agent arguments: '$@'" | |
if [[ "$@" != '--keep' ]] | |
then | |
debug_ "killing existing agents" | |
if [[ "$@" == '--silent' ]] | |
then | |
kill-ssh-agent &> /dev/null | |
else | |
kill-ssh-agent | |
fi | |
else | |
debug_ "keeping existing agents" | |
fi | |
ssh-agent > ~/.ssh/agent.sh | |
connect-ssh-agent #run it | |
reformat-agentsh | |
} | |
reformat-agentsh(){ | |
Line1="SSH_AUTH_SOCK=$SSH_AUTH_SOCK; export SSH_AUTH_SOCK;" | |
Line2="SSH_AGENT_PID=$SSH_AGENT_PID; export SSH_AGENT_PID;" | |
if windows | |
then | |
export SSH_AGENT_WINPID=$(ps | grep $SSH_AGENT_PID | grep -v grep | awk '{print $4}') | |
Line3="SSH_AGENT_WINPID=$SSH_AGENT_WINPID; export SSH_AGENT_WINPID;" | |
fi | |
Line4="echo Agent winpid $SSH_AGENT_WINPID;" | |
Line5="echo Agent pid $SSH_AGENT_PID;" | |
debug_ "$Line1\n$Line2\n$Line3\n$Line4\n$Line5\n" | |
printf "$Line1\n$Line2\n$Line3\n$Line4\n$Line5\n" > ~/.ssh/agent.sh | |
} | |
debug_ "debug mode on" | |
if [ -z "$CYGWIN_SHELL" ] && [ -z "$MSYS_SHELL" ] | |
then | |
sshcount=0 | |
# To ensure we connect across ttys and even if we didn't run it at the tty level | |
# we need to check a number of things. (and that it works on windows) | |
# Check: | |
# that there is at least one agent running | |
# that the running agent is referenced inside agent.sh | |
# If it is not the agent referenced inside agent.sh the user may have multiple running | |
for pid in $(get-agents | get-pid) | |
do | |
((sshcount++)) | |
done | |
debug_ "ssh-agent count: $sshcount" | |
if ((sshcount == 0)) | |
then | |
# Start agent | |
debug_ "user has no ssh-agents open" | |
start-ssh-agent --keep | |
#--keep micro-optimization | |
else | |
# Connect to existing agent | |
debug_ "attempting to connect to the ssh-agent referenced inside agent.sh" | |
connect-ssh-agent 1> /dev/null | |
# we want to display the connection info at the end, so we save it | |
if ssh-add -l 2>&1 | grep "Error" &> /dev/null | |
then | |
# Start agent after failed connection attempt | |
debug_ "ssh agent not connected or started" | |
start-ssh-agent 1> /dev/null | |
elif windows | |
then | |
# Windows? this probably doesn't work | |
debug_ "Okay, we are connected to an agent but let's check that it is the PID inside agent.sh" | |
PID=0 | |
for pid in $(get-agents | get-pid) | |
do | |
if [[ $pid == $SSH_AGENT_WINPID ]] | |
then | |
debug_ "PID from agent.sh is running" | |
PID=$pid | |
break | |
fi | |
done | |
if ((PID == 0)) | |
then | |
debug_ "Could not find PID from agent.sh" | |
start-ssh-agent --keep 1> /dev/null | |
fi | |
fi | |
print-ssh-connection-info | |
fi | |
fi | |
if ! windows; then | |
rm -rf $lock | |
flock -u 3 | |
fi | |
#unset -f get-agents | |
#unset -f get-pid |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works on Windows(git for windows bash) and Linux.
Uses functions from functions.bash
functions used:
newlock
releaselock
blockon
debug_
sort of.. usually it is disabled so..Intended to be loaded in
.bashrc
to connect your terminal(s) to an existing ssh-agent's which must have been started by this script.Adds functions for easy command line intervention.
kill-ssh-agent
(kills all you own)start-ssh-agent
(starts an ssh-agent, also prepares and saves ~/.ssh/agent.sh for other terminals to use.)connect-ssh-agent
(connects terminals to the most recent started ssh-agent [via start-ssh-agent])rewrite-agentsh
intended for in script use. This is needed on windows to ensure future terminals can find the ssh-agent runningOn windows the PID reported in the ssh-agent output will not match what the windows task manager sees, or process explorer. It will match what
ps
sees however, which also reports the WINPID.. so the script finds the WINPID via the PID and saves it to the~/.ssh/agent.sh
script, along with the otherssh-agent
output.I almost wrote an issue in the git for windows issue tracker, until I realized the PID was matching the
ps
outputted PID. It was quite concerning when ssh-agent wasn't detecting the correct PID. Then I realized bash was providing a PID and WINPID. I initially switched to just using the PID for bash, but had a bug pop up where it couldn't find the PID after having closed Cmder/ConEmu.