在Paramiko中运行交互式命令

Sha*_*ila 37 python ssh paramiko

我正试图通过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")
Run Code Online (Sandbox Code Playgroud)

有谁知道如何解决这个问题?谢谢.

Jam*_*ady 30

完整的paramiko发行版附带了很多很好的演示.

在demos子目录中,demo.pyinteractive.py有完整的交互式TTY示例,这可能对您的情况有点过分.

在上面的示例中,ssh_stdin行为类似于标准的Python文件对象,ssh_stdin.write因此只要通道仍处于打开状态,它就应该工作.

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

  • 修复断开的链接。 (3认同)
  • 并且,对于那些想要只看到命令输出可能是什么的人,一些代码可能是:`(stdin,stdout,stderr)= Client.exec_command('ls -la')print("\nstdout是:\n"+ stdout.read()+"\nstderr is:\n"+ stderr.read())` (2认同)

afr*_*eve 10

尝试使用ssh(Paramiko的一个分支)进行交互式ssh会话时遇到了同样的问题.

我挖了一遍,找到了这篇文章:

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()
Run Code Online (Sandbox Code Playgroud)

本文更深入,描述了exec_command周围的完全交互式shell.我发现这比源代码中的示例更容易使用.

  • 链接坏了:( (6认同)

小智 5

您需要Pexpect才能兼得两者(expect和ssh包装器)。


小智 5

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()              
Run Code Online (Sandbox Code Playgroud)

为什么 stdout.read() 如果直接使用而不检查 stdout.channel.recv_ready() 会挂起:在而 stdout.channel.exit_status_ready() 中:

就我而言,在远程服务器上运行命令后,会话正在等待用户输入,输入 'q' 后,它将关闭连接。但是在输入 'q' 之前,stdout.read() 将等待 EOF,如果缓冲区较大,则此方法似乎不起作用。

  • 我在 while 中尝试了 stdout.read(1) ,它有效
    我在 while 中尝试了 stdout.readline() ,它也有效。
    stdin, stdout, stderr = ssh.exec_command('/Users/lteue/Downloads/uecontrol')
    stdout.read() 将挂起