2008-12-17 230 views
31

我试图通过paramiko运行交互式命令。 cmd执行会尝试提示输入密码,但我不知道如何通过paramiko的exec_command提供密码并执行挂起。如果cmd执行期望以交互方式输入,是否有办法将值发送到终端?在Paramiko中运行交互式命令

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") 

有没有人知道如何解决这个问题?谢谢。

+1

的问题是旧的,但为人民谁仍然来到这里通过谷歌搜索我想给他们this.The关键是要得到自己的**频道** [通过Paramiko第1部分在Python中执行交互命令](https://www.youtube.com/watch?v=Jc2l- n_GYPI)[通过Paramiko第2部分在Python中执行交互命令](https://www.youtube.com/watch?v=lLKdxIu3-A4)在这两个视频中,解释了如何通过paramiko运行交互命令,特别是第二个视频是很好,可能你需要什么。 – 2015-01-26 16:50:10

回答

26

完整的paramiko分布附带了很多很好的demos

在演示子目录中,demo.pyinteractive.py具有完整的交互式TTY示例,这可能会对您的情况有所杀伤。

在你上面的例子中ssh_stdin就像一个标准的Python文件对象,所以ssh_stdin.write应该工作,只要通道仍然是打开的。

我从来不需要写入标准输入,但是文档建议只要命令退出就关闭频道,所以使用标准的stdin.write方法发送密码可能不起作用。通道本身有较低级别的paramiko命令,可以让您更好地控制 - 请参阅如何对所有血腥细节实施SSHClient.exec_command方法。

+1

对于那些只想看看命令输出结果的人,有些代码可能是: `(stdin,stdout,stderr)= Client.exec_command('ls -la') print (“\ nstdout is:\ n”+ stdout.read()+“\ nstderr is:\ n”+ stderr.read()) ` – 2011-04-11 17:46:33

+1

`SSHClient.exec_command`Link死了 – Ludisposed 2017-06-11 11:09:38

+1

修复了断开的链接。 – scy 2017-11-16 19:34:50

5

您需要Pexpect才能获得两全其美(expect和ssh包装)。

6

我有同样的问题尝试使用ssh交互式ssh会话,Paramiko的分支。

我挖了一圈,发现这篇文章:

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。我发现这比源代码中的例子更容易使用。

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()将挂起,如果使用dierectly而不检查标准输出。 channel.recv_ready():在while stdout.channel.exit_status_ready():

对我来说,在远程服务器上运行命令后,会话正在等待用户输入,之后在把'Q',它会关闭连接。 但在输入'q'之前,stdout。read()将等待EOF,看起来这个方法在缓冲区较大时不起作用。

  • 我在试图同时stdout.read(1),它的工作原理
    我试图同时stdout.readline(),它的工作原理也。
    标准输入,标准输出,标准错误= ssh.exec_command( '/用户/ lteue /下载/ uecontrol')
    stdout.read()将挂起