我正在尝试通过paramiko运行交互式命令。 cmd执行尝试提示输入密码但我不知道如何通过paramiko的exec_command提供密码并且执行挂起。如果cmd执行需要交互式输入,是否有办法将值发送到终端?
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")
有谁知道如何解决这个问题?谢谢。
答案 0 :(得分:29)
完整的paramiko发行版附带了很多好demos。
在demos子目录中,demo.py
和interactive.py
具有完整的互动TTY示例,这些示例可能会因您的情况而过度。
在上面的示例中,ssh_stdin
的行为类似于标准的Python文件对象,因此只要频道仍处于打开状态,ssh_stdin.write
就可以正常工作。
我从来不需要写入stdin,但文档建议一旦命令退出就关闭一个通道,因此使用标准stdin.write
方法发送密码可能不起作用。通道本身有较低级别的paramiko命令,可以为您提供更多控制 - 请参阅如何为所有血腥细节实施SSHClient.exec_command
方法。
答案 1 :(得分:10)
尝试使用ssh(Paramiko的分支)进行交互式ssh会话时遇到了同样的问题。
我挖了一遍,找到了这篇文章:
更新了链接(链接生成404之前的最新版本):http://web.archive.org/web/20170912043432/http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/
继续你的例子你可以做
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("psql -U factory -d factory -f /tmp/data.sql")
ssh_stdin.write('password\n')
ssh_stdin.flush()
output = ssh_stdout.read()
本文更深入,描述了exec_command周围的完全交互式shell。我发现这比源中的示例更容易使用。
原始链接:http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/
答案 2 :(得分:4)
你需要Pexpect来充分利用这两个世界(期望和ssh包装)。
答案 3 :(得分:3)
我不熟悉paramiko,但这可能有用:
ssh_stdin.write('input value')
ssh_stdin.flush()
有关stdin的信息:
http://docs.python.org/library/sys.html?highlight=stdin#sys.stdin
答案 4 :(得分:3)
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()
为什么stdout.read()会在没有检查stdout.channel.recv_ready()的情况下正确使用时挂起:in stdout.channel.exit_status_ready():
对于我的情况,在远程服务器上运行命令后,会话正在等待用户输入,在输入' q' ,它将关闭连接。 但在输入' q'之前,stdout.read()将等待EOF,如果缓冲区较大,似乎这个方法不起作用。
答案 5 :(得分:0)
看看示例并以类似方式执行
(来自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('lol\n')
stdin.flush()
data = stdout.read.splitlines()
for line in data:
if line.split(':')[0] == 'AirPort':
print line
答案 6 :(得分:0)
您可以使用此方法发送所需的任何确认消息,例如“确定”或密码。这是我的示例解决方案:
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)