On Linux systems it’s common to use ssh-agent (manpage) to store SSH keys. When you run the agent its output can be used to configure it within your shell. The variables defined allow
ssh-add to find the agent once it’s started.
$ ssh-agent SSH_AUTH_SOCK=/tmp/ssh-RRekSLl29890/agent.29890; export SSH_AUTH_SOCK; SSH_AGENT_PID=29891; export SSH_AGENT_PID; echo Agent pid 29891;
I use an Ubuntu VM, and regularly log in using PuTTY. It’s easy to connect to the agent on login, but I wanted a way to keep connecting back to the same one so I could add keys and leave them there. There’s loads of solutions available, but I wanted to try and write a simpler version.
- Store the agent settings into a file under
- Load the file on login
- Check whether the agent can be found, and if it can’t start it
This is slightly more subtle than it first appears: it’s necessary to cope with the file not existing and containing out-of-date data, and I wanted to do this as tidily as possible.
Here’s my solution:
[ -f ~/.ssh/agent_env ] && . ~/.ssh/agent_env kill -0 $SSH_AGENT_PID 2> /dev/null || . <(ssh-agent | tee ~/.ssh/agent_env)
First we check if the file exists:
[ -f ~/.ssh/agent_env ]
If it does then we execute its contents using a bash shortcut (the ‘
If the file did exist then we should have a value for the
SSH_AGENT_PID. We check whether it’s possible to send a signal to the process this identifies using
kill -0 $SSH_AGENT_PID
The nice thing about this is that if the variable isn’t defined then we end up passing garbage on to
kill, and it’ll return false in the same way as if the process didn’t exist. We add a redirect to
/dev/null so we don’t see its helpful error message.
kill -0 $SSH_AGENT_PID 2> /dev/null
Now we just need to run the agent, store its output in the file, and use that output to configure the shell. We can use a bash trick to load the agent and configure the shell in one tidy step:
The redirect here has the effect of attaching the ssh-agent output to a file descriptor, and then returning the path to that file descriptor. It’s convenient when you want to pass the output of a command to one which is expecting a filename.
Finally we insert a call to
tee which writes out our file.
. <(ssh-agent | tee ~/.ssh/agent_env)