在Paramiko中运行交互式命令
我试图通过paramiko运行一个交互式命令。 cmd执行尝试提示input密码,但我不知道如何通过paramiko的exec_command提供密码,执行挂起。 如果cmd执行需要交互式input,有没有办法将值发送到terminal?
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")
有谁知道这可以解决? 谢谢。
完整的paramiko发行版附带了很多好的演示 。
在演示子目录中, demo.py
和interactive.py
有完整的交互式TTY示例,这可能会对您的情况有所demo.py
。
在上面的例子中, ssh_stdin
行为就像一个标准的Python文件对象,所以只要通道仍然打开, ssh_stdin.write
可以工作。
我从来没有必要写stdin,但是文档build议只要一个命令退出就closures一个通道,所以使用标准的stdin.write
方法发送密码可能不起作用。 通道本身有较低级别的paramiko命令,可以提供更多控制 – 请参阅SSHClient.exec_command
方法是如何实现所有血淋淋的细节的。
我有同样的问题尝试使用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()
文章更深入地描述了围绕exec_command的完全交互式shell。 我发现这比源代码中的例子更容易使用。
你需要Pexpect来获得两全其美(expect和ssh包装)。
我不熟悉paramiko,但这可能工作:
ssh_stdin.write('input value') ssh_stdin.flush()
有关标准input的信息:
http://docs.python.org/library/sys.html?highlight=stdin#sys.stdin
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():在而stdout.channel.exit_status_ready():
对我来说,在远程服务器上运行命令后,会话正在等待用户input,input'q'后会closures连接。 但在input'q'之前,stdout.read()将等待EOF,如果缓冲区较大,似乎这个方法不起作用。
- 我尝试了stdout.read(1),而它的工作原理
我在尝试stdout.readline()的同时,它也可以。
stdin,stdout,stderr = ssh.exec_command('/ Users / lteue / Downloads / uecontrol')
stdout.read()将挂起
看看例子,以类似的方式做
(来自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