The following is something I use to manage my ssh agent settings.

#!/bin/echo "Must source this:" 
## Ensure that ~/.ssh/env contains valid values


[ -r ~/.ssh/env ] && . ~/.ssh/env
[ -n "$SSH_AGENT_PID" ]  || {
    # No env file (or it's badly corrupted:
    eval $(ssh-agent &>/dev/null) &> /dev/null

# Ping the agent process:
kill -0 "$SSH_AGENT_PID" >& /dev/null || {
    # No process, so start a new one:
    eval $(ssh-agent &>/dev/null) &> /dev/null

ssh-add -l &> /dev/null
[ "$?" -gt 1 ] && {
    # Process alive but unable to be contacted
    # for some reason (wedged/defunct process,
    # or damaged/corrupt UNIX domain socket node?)

    # So kill it:
    kill "$SSH_AGENT_PID" >& /dev/null
    # ... with extreme prejudice if necessary:
    kill -0 "$SSH_AGENT_PID" >& /dev/null \
    || kill kill -9 "$SSH_AGENT_PID" >& /dev/null

    # ... and start a new one
    eval $(ssh-agent &>/dev/null) &> /dev/null

[ -z "$SSH_ENV_REFRESH" ] || {
    # Over-write old env file:
    printenv | grep "^SSH_A" > ~/.ssh/env
    # Append export command:
    echo "export SSH_AGENT_PID SSH_AUTH_SOCK" >> ~/.ssh/env

    # Load the (null-passphrase) identites into the agent:
    ssh-add  < /dev/null &> /dev/null

It's intended to be sourced (. ~/lib/sshagent.sh) from ~/.bashrc or other login or shell start-up files ... or even cron jobs. It works for me but I'm hoping folks here will review it and offer suggestions about any corner cases that I'm missing.

I used to only run it from ~/.bash_login ... but then I'd find that, in some cases, my shells wouldn't pick up the settings (X display manager and I think remote ssh non-login sessions ... cases where ssh is called with a command). In some other cases the old settings would persist and not updated when an agent process was restarted (for whatever reason). So I run it in ~/.bashrc and try to avoid any stray output ... as is recommended for ~/.bashrc in general.

So, are there any evident corner cases or bugs? Would this make sense for something like /etc/bashrc? Is it reasonably portable to other shells?


One portability issue in your script is the use of &> /dev/null to redirect both stdout and stderr. This is a bashism and won't necessarily work on other shells. (I was recently bitten by this one.) The more portable way is to use > /dev/null 2>&1.


Why are you writing your own? why not use a handy dandy little product called keychain?

Here's Gentoo's Keychain Guide (possibly newer version of same article on Funtoo)

It's basically a little program that allows you to use password protected keys, without typing the password all the time. (It should be available on whatever distro you're using)

You may also be interested in Gentoo's Open SSH Key Management series: part 1, part 2, and part 3. Which looks like it includes some things that you're trying to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.