我正在将Paramiko用于 tail -f
远程服务器上的文件 .
以前,我们通过 ssh -t
运行此功能,但事实证明这种情况不稳定, -t
导致我们的远程调度系统出现问题 .
我的问题是当脚本捕获SIGINT时如何杀死尾巴?
我的脚本(基于Long-running ssh commands in python paramiko module (and how to end them))
#!/usr/bin/env python2
import paramiko
import select
client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('someserver', username='victorhooi', password='blahblah')
transport = client.get_transport()
channel = transport.open_session()
channel.exec_command("tail -f /home/victorhooi/macbeth.txt")
while True:
try:
rl, wl, xl = select.select([channel],[],[],0.0)
if len(rl) > 0:
# Must be stdout
print channel.recv(1024)
except KeyboardInterrupt:
print("Caught control-C")
client.close()
channel.close()
exit(0)
该脚本成功捕获我的Ctrl-C,然后结束 . 但是,它使 tail -f
进程在远程系统上运行 .
client.close()和channel.close()似乎都没有终止它 .
我可以在except块中发出什么命令来杀死它?
远程服务器正在运行Solaris 10 .
8 回答
虽然不是最有效的方法,但这应该有效 . CTRL C之后;在KeyboardInterrupt处理程序中,你可以
exec_command("killall -u %s tail" % uname)
像这样:这会杀死任何名为
tail
的打开进程 . 这可能会导致问题,但如果你打开了tail
,你不想关闭,如果是这样你可以grep
aps
,得到pid和kill -9
它 .首先,设置tail以从文件末尾读取
n
行,然后再执行 . 将n
设置为一个独特的nuber,如time.time()
,因为尾部不关心该数字是否大于文件中的行数,time.time()
中的大数字不应该导致问题并且将是唯一的 . 然后grep为ps
中的唯一编号:有一种方法可以做到这一点 . 它就像在shell上一样
选项-t是打开一个伪pty来帮助ssh跟踪这个过程应该持续多长时间 . 同样可以通过pormiko via完成
在execute_command(...)之前 . 这不会像使用channel.invoke_shell()一样打开shell,它只是请求这样的伪接口将所有进程绑定到 . 如果在远程计算机上发出ps aux,也可以看到效果,此过程现在通过ptxXY接口附加到sshd .
你应该使用ssh keepalive ...你遇到的问题是远程shell无法知道(默认情况下)你的ssh会话被杀死了 . Keepalive将使远程shell能够检测到您已杀死会话
将keepalive值设置为您想要的最低值(甚至1秒)......几秒钟后,远程shell将看到ssh登录名死亡,它将终止由它生成的任何进程 .
我刚刚遇到这个问题,并且无法在最后发出关闭该过程的pkill .
更好的解决方案是将您正在运行的命令更改为:
这将允许您根据需要运行tail命令 . 只要您向远程进程发送换行符,kill%1就会执行并停止后退命令 . (供参考:%1是一个jobspec,用于描述在会话中已经背景化的第一个进程,即tail命令)
这是获取远程进程ID的一种方法:
以下是如何使用它(用原始问题中的位替换
...
):特别是对于'tail',你可以使用--pid = PID参数并让tail来处理它:
您可以使用https://stackoverflow.com/a/38883662/565212中所述的get_pty .
例如 . scenario - 何时调用client / channel.close():
步骤1:执行写入日志文件的远程命令 .
Step2:生成一个执行tail命令的线程,并在readline循环中阻塞
Step3:在主线程中,当命令返回时,你知道将不再有日志,杀死尾线程 .
与
ssh -t
有同样的问题 . 有一个名为closer的库 - 它通过ssh运行远程进程并自动关闭 . 看看这个 .