Common problem: you want to use ssh-agent with Cygwin, but because Windows is special, you can’t inherit the environment in the way you naturally would on a Unix or Linux system.
Now, before I proceed, understand that this is a HorribleHackā¢; it is the equivalent of modifying your .bashrc every time you login.
For this to work, you need to have the setx utility installed, which you need to download if you’re still using XP.
The first step is to save the following script; I put it in ~/bin/, but you could safely put it into /usr/bin as it only modifes the environment of the person who runs it. I used Python 3 because I could and because everyone should.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#!/bin/bash # Start an SSH Agent process and export the values to the System, so all # Cygwin shells can inherit it. nohup /usr/bin/ssh-agent -c | /usr/bin/python3 -c " import sys import os import subprocess def main(argv): ssh_agent_pid = None input = sys.stdin.read().split() # Validate the input try: if ( input[0] != 'setenv' or input[3] != 'setenv' or input[1] != 'SSH_AUTH_SOCK' or input[4] != 'SSH_AGENT_PID' ): raise Exception('bad input') # Need to chomp the semi-colon at the end of each line. ssh_agent_socket = input[2][:-1] ssh_agent_pid = input[5][:-1] # Set the variables. subprocess.check_call(['setx', 'SSH_AUTH_SOCK', ssh_agent_socket]) subprocess.check_call(['setx', 'SSH_AGENT_PID', ssh_agent_pid]) return 0 except Exception as ex: print(str(ex)) if ssh_agent_pid is not None: os.kill(ssh_agent_pid, 9) return 1 if __name__ == '__main__': sys.exit(main(sys.argv)) " |
Next, create a shortcut in your Startup Folder. I called it simply “SSH Agent”.
The command line you will need (the Target field in the shortcut), is:
1 |
C:\cygwin\bin\run.exe -p /bin bash ~/bin/start-ssh-agent |
There seems to be an undocumented feature of run, that requires one to set the -p option to something or it will fail. Obviously, if you’ve installed the 64-bit version of Cygwin or put the start-ssh-agent script somewhere else, you’ll need to change your paths accordingly.
I haven’t written the symmetrical stop-ssh-agent, because I’m lazy and Windows doesn’t provide a convenient location to run scripts at log-off (you mess with group policies if you want, but I have more interesting things to be doing…)
Very useful, thanks. Not being a Python disciple (yet), I turned this into a shell script. If you source it (source script or . script), it even sets the required environment variables in the current shell:
#!/bin/bash
# set up ssh-agent if it isn’t running yet
NAGENTS=$(pgrep ssh-agent|wc -l)
if [ “$NAGENTS” -eq 1 ]
then
echo “ssh-agent already running”
PID=$(pgrep ssh-agent)
if [ “$SSH_AGENT_PID” -ne “$PID” ]
then
echo SSH_AGENT_PID is $SSH_AGENT_PID, but agent PID is “$PID”
echo Please fix this manually
fi
elif [ “$NAGENTS” -gt 1 ]
then
echo “more than one ssh-agent already running!! Manual fix required”
else
SSH_ENV=$(ssh-agent -s | grep -v Agent)
eval $SSH_ENV
# setx sets environment variable for Windows
setx SSH_AUTH_SOCK $SSH_AUTH_SOCK 2>&1 >/dev/null
setx SSH_AGENT_PID $SSH_AGENT_PID 2>&1 >/dev/null
echo $SSH_ENV
fi