Question :
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.
Answer #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.
Answer #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/
Answer #3:
You need Pexpect to get the best of both worlds (expect and ssh wrappers).
Answer #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
Answer #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
Answer #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
Answer #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)