title: How can I make my custom shell work with ssh?
body: <p>I'm making a custom shell in Python for a very limited user on a server, who is logged in via ssh with a public key authentication. They need to be able to run <code>ls</code>, <code>find -type d</code>, and <code>cat</code> in specific directories with certain limitations. This works fine if you run something like <code>ssh user@server -i keyfile</code>, because you see the interactive prompt, and can run those commands. However, something like <code>ssh user@server -i keyfile "ls /var/log"</code> doesn't. <code>ssh</code> simply hangs, with no response. By using the <code>-v</code> switch I've found that the connection is succeeding, so the problem is in my shell. I'm also fairly certain that the script isn't even being started, since <code>print sys.argv</code> at the beginning of the program does nothing. Here's the code:</p>
  
  <pre><code>#!/usr/bin/env python
  
  import subprocess
  import re
  import os
  
  with open(os.devnull, 'w') as devnull:
      proc = lambda x: subprocess.Popen(x, stdout=subprocess.PIPE, stderr=devnull)
  
      while True:
          try:
              s = raw_input('&gt; ')
          except:
              break
  
          try:
              cmd = re.split(r'\s+', s)
              if len(cmd) != 2:
                  print 'Not permitted.'
                  continue
              if cmd[0].lower() == 'l':
                  # Snip: verify directory
                  cmd = proc(['ls', cmd[1]])
                  print cmd.stdout.read()
              elif cmd[0].lower() == 'r':
                  # Snip: verify directory
                  cmd = proc(['cat', cmd[1]])
                  print cmd.stdout.read()
              elif cmd[0].lower() == 'll':
                  # Snip: verify directory
                  cmd = proc(['find', cmd[1], '-type', 'd'])
                  print cmd.stdout.read()
              else:
                  print 'Not permitted.'
          except OSError:
              print 'Unknown error.'
  </code></pre>
  
  <p>And here's the relevant line from ~/.ssh/authorized_keys:</p>
  
  <pre><code>command="/path/to/shell $SSH_ORIGINAL_COMMAND" ssh-rsa [base-64-encoded-key] user@host
  </code></pre>
  
  <p>How can I make the shell script when the command is passed on the command line so it can be used in scripts without starting an interactive shell?</p>