title: Python - communicating with subprocess over a socket
body: <p>I am looking to replicate the way programs like Git and Rsync communicate and transfer data over an SSH connection, but in Python. I understand that these programs fork and exec an SSH command that starts a process on the server side and communication is achieved by the parent processing talking to the STDIN and STDOUT of the forked child process.</p>
  
  <p>In C I have seen this done by creating a Unix socket pair (s0, s1), forking the process, pointing the stdin/stdout of the forked process to s1 on the child process, and then reading and writing to the socket s0 on the parent process.</p>
  
  <p>I want to do the same thing in Python3. As a proof of concept, here is my implementation of a toy remote shell that sends commands down a socket and receives the output from the same socket:</p>
  
  <pre><code>import subprocess
  import socket
  
  
  ssh_cmd = 'ssh -q -T ubuntu@xxxxxxxx'
  s_local, s_remote = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
  
  ssh = subprocess.Popen(ssh_cmd, shell=True,
                         stdout=s_remote,
                         stdin=s_remote,
                         close_fds=True)
  s_remote.close()
  
  s_local.send('ls -l\n'.encode())
  print(s_local.recv(1024).decode())
  s_local.send('uname -a\n'.encode())
  print(s_local.recv(1024).decode())
  s_local.close()
  ssh.kill()
  </code></pre>
  
  <p>This kind of works. But I can deadlock it if I send 'true \n' down the socket because 'recv' is blocking so that's not great.</p>
  
  <ol>
  <li>Is this a sensible/common thing to do in network programming?</li>
  <li>What is a more idiomatic way of doing this using the Python3 standard libraries that doesn't deadlock?</li>
  </ol>