use*_*925 22 python ssh paramiko
我想tail -f logfile使用python的paramiko模块在远程机器上运行命令.到目前为止,我一直在尝试以下方式:
interface = paramiko.SSHClient()
#snip the connection setup portion
stdin, stdout, stderr = interface.exec_command("tail -f logfile")
#snip into threaded loop
print stdout.readline()
Run Code Online (Sandbox Code Playgroud)
我希望命令在必要时运行,但我有两个问题:
shutdown()在我通过时使用频道上的命令 - 但这看起来很混乱.有可能做一些像发送Ctrl-C到频道的标准输入的东西吗?readline() 块,如果我有一个非阻塞的输出方法,我可以避免线程 - 任何想法?And*_*ett 21
不要在客户端上调用exec_command,而是抓住传输并生成自己的通道.该通道可用于执行命令,您可以在select语句中使用它来查找何时可以读取数据:
#!/usr/bin/env python
import paramiko
import select
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('host.example.com')
transport = client.get_transport()
channel = transport.open_session()
channel.exec_command("tail -f /var/log/everything/current")
while True:
rl, wl, xl = select.select([channel],[],[],0.0)
if len(rl) > 0:
# Must be stdout
print channel.recv(1024)
Run Code Online (Sandbox Code Playgroud)
可以读取和写入通道对象,与远程命令的stdout和stdin连接.你可以通过电话联系stderr channel.makefile_stderr(...).
我已将超时设置为0.0秒,因为请求了非阻塞解决方案.根据您的需要,您可能希望使用非零超时进行阻止.
Jim*_*imB 14
1)如果您愿意,您可以关闭客户端.另一端的服务器将终止尾部进程.
2)如果您需要以非阻塞方式执行此操作,则必须直接使用通道对象.然后,您可以使用channel.recv_ready()和channel.recv_stderr_ready()来查看stdout和stderr,或使用select.select.
只是Andrew Aylett对解决方案的一个小更新.以下代码实际上打破了循环并在外部进程完成时退出:
import paramiko
import select
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('host.example.com')
channel = client.get_transport().open_session()
channel.exec_command("tail -f /var/log/everything/current")
while True:
if channel.exit_status_ready():
break
rl, wl, xl = select.select([channel], [], [], 0.0)
if len(rl) > 0:
print channel.recv(1024)
Run Code Online (Sandbox Code Playgroud)