Using SSH agent on Windows with Cmder and without eval

Please see the bottom of the page for an update from 2016/08/30.

I’ve been using Cmder for around a year now, and I really like it. It provides me with the goodness of some bash features along with many GNU commands that Linux and Unix users will be familiar with, while fitting in well on top of the Windows Command Prompt. It does this by packaging together several separate pieces of software such as ConEmu, Clink and Msysgit along with a nice looking theme and a lot of scope for customisation.

While you can use a full Bash shell under Cmder, I tend towards the Clink based mix of Bash, familiar commands and command prompt. One issue I’ve found, is that many systems running this configuration will make it hard to run ssh-agent, meaning you have to enter your SSH key passphrase every time you interact with SSH (if you use Git, you probably do this a lot).

Most of the information available online points to using either eval `ssh-agent -s` or eval $(ssh-agent -s). If either of these work for you – great! It certainly works if you go for a full Bash environment. If you don’t have any success, read on.

I want to be able to start an SSH agent in the first terminal I start up, one for each terminal would be inefficient, and a duplication of password entry. Cmder provides you access to a startup script, similar to the .bashrc or .profile files used for Bash. This can be found within the “vendor” folder of Cmder’s program files, the script is a batch script named init.bat.

I’ve added the following to this script (I added it toward the bottom of the script to ensure that the bash command was available):


:: Run ssh-agent initialisation
@if "%SSH_AGENT_PID%"=="" (
@bash D:/cmder/bin/ssh-agent-init.sh
@call ssh-agent-setter.cmd
@del ssh-agent-setter.cmd
ssh-add %USERPROFILE%/.ssh/id_rsa
) else (
@echo SSH Agent already running with PID %SSH_AGENT_PID%
)

vendor/init.bat


#! /bin/bash
eval `ssh-agent -s`
echo "@SET SSH_AGENT_PID="$SSH_AGENT_PID>ssh-agent-setter.cmd
echo "@SET SSH_AUTH_SOCK="$SSH_AUTH_SOCK>>ssh-agent-setter.cmd

bin/ssh-agent-init.sh

The “@” symbol supresses on-screen printing per command, and is used throughout the rest of the script. This code checks to see if the variable SSH_AGENT_PID has been set (one of the two variables which the ssh-agent command attempts to export, and one of the two variables which is required by ssh-add to add your key to the agent). If it hasn’t already been set, the script runs the bash script ssh-agent-init.sh, which I have placed in my “bin/” directory in the Cmder program files, but can be placed anywhere that is accessible to init.bat.

This bash script calls the ssh-agent command under Bash, which works as previously stated, and effectively exports the variables defined by ssh-agent to command prompt and Windows environment variables by generating a batch script with variable setters for each value. Once the bash script exits, the batch script is called and deleted straight after.

Finally, with the required environment variables in place, ssh-add is called, with the default SSH key location specified, though this can be changed or even requested from the user on each start up.

For as long as Cmder remains open, these environment variables will remain defined. Duplicating the terminal in Cmder will also duplicate these environment variables. Duplicated terminals will simply get a message informing the user that an SSH agent is already running, though it may be more desirable to suppress any message entirely in this case.

New SSH agents would be started up if entirely separate terminal tabs are opened, but this didn’t pose a huge problem to me as I usually leave Cmder open and duplicate my current terminal. This script could be tweaked to save the environment variables so long as the ssh-agent was still running (which it wouldn’t across restarts of the machine). I’d also imagine the script could be tweaked to generate the bash script too, thereby not requiring any extraneous scripts, however, it acts as a quick way of calling ssh-agent manually, which is why ssh-agent-init.sh is within the bin folder.

Update 2016/08/30: While the above method does still work, I later discovered that there is a whole command built to get the ssh-agent working correctly already in Cmder. It’s a file called start-ssh-agent.cmd (how appropriate!) and it may already be in your PATH while in Cmder. Try running the command with its full name, if you get an error, it’s probably easiest to search the entire Cmder directory for that file name. Once you find its location, call it in vendor/init.bat instead and everything should work as expected.

Advertisements