47

我正在尝试通过 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")

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

4

7 回答 7

32

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

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

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

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

于 2008-12-17T07:12:19.363 回答
12

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

我翻遍了,发现了这篇文章:

更新链接(链接生成 404 之前的最后一个版本):http ://web.archive.org/web/20170912043432/http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely -不同的/

要继续您的示例,您可以这样做

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/

于 2012-09-14T19:58:35.053 回答
5

您需要 Pexpect 来获得两全其美的效果(expect 和 ssh 包装器)。

于 2010-06-22T18:51:33.310 回答
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()              

如果直接使用而不检查 stdout.channel.recv_ready(): 为什么 stdout.read() 会挂起,而 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() 将挂起
于 2016-09-28T07:39:47.537 回答
3

我不熟悉 paramiko,但这可能有效:

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

有关标准输入的信息:

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

于 2008-12-17T05:44:53.377 回答
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
于 2016-05-30T08:28:50.450 回答
0

您可以使用此方法发送您想要的任何确认消息,例如“OK”或密码。这是我的示例解决方案:

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)
于 2019-06-24T22:13:07.253 回答