Running interactive commands in Paramiko

I’m trying to run an interactive command through paramiko. The cmd execution tries to prompt for a password but I do not know how to supply the password through paramiko’s exec_command and the execution hangs. Is there a way to send values to the terminal if a cmd execution expects input interactively?

ssh = paramiko.SSHClient()
ssh.connect(server, username=username, password=password)
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")

Does anyone know how this can addressed? Thank you.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The full paramiko distribution ships with a lot of good demos.

In the demos subdirectory, demo.py and interactive.py have full interactive TTY examples which would probably be overkill for your situation.

In your example above ssh_stdin acts like a standard Python file object, so ssh_stdin.write should work so long as the channel is still open.

I’ve never needed to write to stdin, but the docs suggest that a channel is closed as soon as a command exits, so using the standard stdin.write method to send a password up probably won’t work. There are lower level paramiko commands on the channel itself that give you more control – see how the SSHClient.exec_command method is implemented for all the gory details.

Method 2

I had the same problem trying to make an interactive ssh session using ssh, a fork of Paramiko.

I dug around and found this article:

Updated link (last version before the link generated a 404): http://web.archive.org/web/20170912043432/http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

To continue your example you could do

ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
ssh_stdin.write('passwordn')
ssh_stdin.flush()
output = ssh_stdout.read()

The article goes more in depth, describing a fully interactive shell around exec_command. I found this a lot easier to use than the examples in the source.

Original link: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

Method 3

You need Pexpect to get the best of both worlds (expect and ssh wrappers).

Method 4

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server_IP,22,username, password)


stdin, stdout, stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol-CXC_173_6456-R32A01/uecontrol.sh -host localhost ')
alldata = ""
while not stdout.channel.exit_status_ready():
   solo_line = ""        
   # Print stdout data when available
   if stdout.channel.recv_ready():
      # Retrieve the first 1024 bytes
      solo_line = stdout.channel.recv(1024) 
      alldata += solo_line
   if(cmp(solo_line,'uec> ') ==0 ):    #Change Conditionals to your code here  
     if num_of_input == 0 :
      data_buffer = ""    
      for cmd in commandList :
       #print cmd
       stdin.channel.send(cmd)        # send input commmand 1
      num_of_input += 1
     if num_of_input == 1 :
      stdin.channel.send('q n')      # send input commmand 2 , in my code is exit the interactive session, the connect will close.
      num_of_input += 1 
print alldata
ssh.close()

Why the stdout.read() will hang if use dierectly without checking stdout.channel.recv_ready(): in while stdout.channel.exit_status_ready():

For my case ,after run command on remote server , the session is waiting for user input , after input ‘q’ ,it will close the connection .
But before inputting ‘q’ , the stdout.read() will waiting for EOF,seems this methord does not works if buffer is larger .

  • I tried stdout.read(1) in while , it works
    I tried stdout.readline() in while , it works also.
    stdin, stdout, stderr = ssh.exec_command(‘/Users/lteue/Downloads/uecontrol’)
    stdout.read() will hang

Method 5

I’m not familiar with paramiko, but this may work:

ssh_stdin.write('input value')
ssh_stdin.flush()

For information on stdin:

http://docs.python.org/library/sys.html?highlight=stdin#sys.stdin

Method 6

Take a look at example and do in similar way

(sorce from http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/):

    ssh.connect('127.0.0.1', username='jesse', 
        password='lol')
    stdin, stdout, stderr = ssh.exec_command(
        "sudo dmesg")
    stdin.write('loln')
    stdin.flush()
    data = stdout.read.splitlines()
    for line in data:
        if line.split(':')[0] == 'AirPort':
            print line

Method 7

You can use this method to send whatever confirmation message you want like “OK” or the password. This is my solution with an example:

def SpecialConfirmation(command, message, reply):
    net_connect.config_mode()    # To enter config mode
    net_connect.remote_conn.sendall(str(command)+'n' )
    time.sleep(3)
    output = net_connect.remote_conn.recv(65535).decode('utf-8')
    ReplyAppend=''
    if str(message) in output:
        for i in range(0,(len(reply))):
            ReplyAppend+=str(reply[i])+'n'
        net_connect.remote_conn.sendall(ReplyAppend)
        output = net_connect.remote_conn.recv(65535).decode('utf-8') 
    print (output)
    return output

CryptoPkiEnroll=['','','no','no','yes']

output=SpecialConfirmation ('crypto pki enroll TCA','Password' , CryptoPkiEnroll )
print (output)


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x