How to use ssh-agent in windows in python?
On 29May2019 22:37, Fc Zwtyds <fczwtyds at gmail.com> wrote:
>? 2019-05-27 11:19, Cameron Simpson ??:
>>The output of "ssh-agent -s" is Bourne shell variable assignment
>>syntax. You need to parse that [...]
> I want to rewrite the shell script to python script so I have had
>changed the "ssh-agent -s" to 'ssh-agent cmd' in python script for the
>consistence on windows.
I'm not sure you need to do that. In fact, I'm fairly sure you don't.
When you run "ssh-agent cmd" the agent starts as before, but instead of
reporting its communication socket and process id it dispatches command
and runs for the duration of that command, then exits.
Before ssh-agent dispatches "cmd" (here I mean a generic command, though
that command might well be "cmd.exe"), it first puts the necessary
environment variables into the command's environment.
There are two such values: the communication socket and the ssh-agent
process id. The socket is so that the other ssh commands can talk to it,
and the process id is so that it can be terminated when no longer
wanted. For the "ssh-agent cmd" form there's no need to use the process
id, since ssh-agent itself will exit after "cmd" finishes.
Let's look at what "ssh-agent -s" produces. This is on a UNIX system (my
[~]fleet*> ssh-agent -s
SSH_AUTH_SOCK=/Users/cameron/tmp/ssh-vuvXU6vrCAxz/agent.50746; export SSH_AUTH_SOCK;
SSH_AGENT_PID=50754; export SSH_AGENT_PID;
echo Agent pid 50754;
You can see the socket path and the process id there. The paths will be
a bit different on Windows.
So if I do a process listing (this is a UNIX "ps" command, you will need
to do the equivalent Windows thing) and search for that process id we
[~]fleet*1> ps ax | grep 62928
62928 ?? Ss 0:00.00 ssh-agent -s
66204 s027 S+ 0:00.00 grep 62928
So there's the ssh-agent process and also the "grep" command itself
because the process id is present on its command line.
Note that at this point my shell (cmd.exe equivalent in Windows) does
not know about the new ssh-agent. This is because I haven't put those
environment values into the shell environment: the output above is just
written to the display. So when I go:
[~]fleet*> ssh-add -l
it shows me 4 ssh keys. This is because I already have an agent which
has some keys loaded. If my shell were talking to the new agent the list
would be empty. Let's do that.
[~]fleet*> export SSH_AUTH_SOCK SSH_AGENT_PID
[~]fleet*> ssh-add -l
The agent has no identities.
So now this shell is using the new agent. You see there's no magic here:
other commands do not know about the agent until we tell then about it
using these environment variables.
What I was suggesting is that you perform this process from Python,
which I believe was your original plan.
So let's adapt the the comand you presented below, and also dig into why
what you've tried hasn't worked. So, your subprocess call:
p = subprocess.Popen('cmd', stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell = True, universal_newlines = True)
outinfo, errinfo = p.communicate('ssh-agent cmd\n')
print('outinfo is \n %s' % stdoutinfo)
print('errinfo is \n %s' % stderrinfo)
This does the follow things:
1: Start a subprocess running "cmd". You get back a Popen object "p" for
use with that process.
2: Run p.communicate("ssh-agent cmd\n"). This sends that to the input of
the "cmd" subprocess and collects the output.
An important thing to know here is the .communicate is a complete
interaction with the subprocess. The subprocess' _entire_ input is the
string you've supplied, and the entire output of the subprocess until it
completes is collected.
So, what's going on is this:
1: start "cmd"
2: send "ssh-agent cmd\n" to it.
3: collect output and wait for it to exit.