windowssshgit-bash

Running SSH Agent when starting Git Bash on Windows


I am using git bash. I have to use

eval `ssh-agent.exe`
ssh-add /my/ssh/location/

every time when I start a new git bash.

Is there a way to set ssh agent permanently? Or does windows has a good way to manage the ssh keys?

I'm a new guy, please give me detailed tutorial, thanks!


Solution

  • 2013: In a git bash session, you can add a script to ~/.profile or ~/.bashrc (with ~ being usually set to %USERPROFILE%), in order for said session to launch automatically the ssh-agent.
    If the file doesn't exist, just create it.

    This is what GitHub describes in "Working with SSH key passphrases".

    The "Auto-launching ssh-agent on Git for Windows" section of that article has a robust script that checks if the agent is running or not.
    Below is just a snippet, see the GitHub article for the full solution.

    # This is just a snippet. See the article above.
    if ! agent_is_running; then
        agent_start
        ssh-add
    elif ! agent_has_keys; then
        ssh-add
    fi
    

    Other Resources:

    "Getting ssh-agent to work with git run from windows command shell" has a similar script, but I'd refer to the GitHub article above primarily, which is more robust and up to date.


    hardsetting adds in the comments (2018):

    If you want to enter the passphrase the first time you need it, and not when opening a shell, the cleanest way to me is:

    This way you don't even have to remember running ssh-add.


    And Tao adds in the comments (2022):

    It's worth noting why this script makes particular sense in Windows, vs (for example) the more standard linuxey script noted by @JigneshGohel in another answer:

    By not relying on the SSH_AGENT_PID at all, this script works across different msys & cygwin environments.
    An agent can be started in msys2, and still used in git bash, as the SSH_AUTH_SOCK path can be reached in either environment.
    The PID from one environment cannot be queried in the other, so a PID-based approach keeps resetting/creating new ssh-agent processes on each switch.


    szx mentions in the comments:

    There is a downside to this solution: Once you kill/exit the initial Git Bash bash.exe instance that started ssh-agent, the agent is not accessible by other shell instances until you open a new one. This is not good.

    Then you can modify the script to make sure ssh-agent persists across different Git Bash sessions. That would involve saving the agent's environment variables in a file that can be sourced by subsequent shells.

    Add the check for an existing ssh-agent process to your ~/.bashrc or ~/.profile, and connect to it, or start a new one if necessary:

    # Define a file to store the SSH agent environment variables
    SSH_ENV="$HOME/.ssh/environment"
    
    # Function to start ssh-agent and save its environment variables
    function start_agent {
        echo "Initializing new SSH agent..."
        # Start new ssh-agent, with the environment variables stored in SSH_ENV
        ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
        echo "succeeded"
        chmod 600 "${SSH_ENV}"
        . "${SSH_ENV}" > /dev/null
        ssh-add
    }
    
    # Source SSH settings, if applicable
    if [ -f "${SSH_ENV}" ]; then
        . "${SSH_ENV}" > /dev/null
        # Check if the agent is running
        ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
            start_agent;
        }
    else
        start_agent;
    fi
    

    The .ssh/environment is used to store the ssh-agent environment variables (SSH_AGENT_PID and SSH_AUTH_SOCK).