如果进程是通过paramiko ssh会话并使用“&"来运行的,则进程终止.到底 [英] Process dies, if it is run via paramiko ssh session and with "&" in the end

查看:331
本文介绍了如果进程是通过paramiko ssh会话并使用“&"来运行的,则进程终止.到底的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只想使用paramiko在后台运行tcpdump.

I just want to run tcpdump in background using paramiko.

这是代码的一部分:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=login, password=password)
transport = ssh.get_transport()
channel = transport.open_session()
channel.get_pty()
channel.set_combine_stderr(True)

cmd = "(nohup tcpdump -i eth1  port 443 -w /tmp/dump20150317183305940107.pcap) &"
channel.exec_command(cmd)
status = channel.recv_exit_status()

执行此代码后,pgrep tcpdump不返回任何内容.

After I execute this code, pgrep tcpdump returns nothing.

如果我删除了&符号,则tcpdump可以正确运行,但是我的ssh shell被阻止了.

If I remove & sign tcpdump runs correctly, but my ssh shell is blocked.

如何在后台正确运行tcpdump?

我尝试过的命令:

cmd = 'nohup tcpdump -i eth1  port 443 -w /tmp/dump20150317183305940107.pcap &\n'
cmd = "screen -d -m 'tcpdump -i eth1  port 443 -w /tmp/dump20150317183305940107.pcap'"
cmd = 'nohup sleep 5 && echo $(date) >> "test.log" &'

推荐答案

使用&,您可以立即退出远程命令.因此,远程sshd可能会(取决于实现,但openssh会)杀死从命令调用启动的所有进程.在您的情况下,您只是生成了一个新的进程nohup tcpdump,该进程最终会由于&而立即返回. channel.recv_exit_status()只会阻塞,直到准备好&操作的退出代码为止.然后,您的代码只是终止,终止了ssh会话,这将使远程sshd杀死生成的nohup tcpdump proc.这就是为什么您最终没有tcpdump进程的原因.

With & you make your remote command exit instantly. The remote sshd will therefore likely (depends on implementation, but openssh does) kill all processes that were started from your command invocation. In your case, you just spawn a new process nohup tcpdump which will instantly return due to & at the end. The channel.recv_exit_status() will only block until the exit code for the & ooperation is ready which instantly is. Your code then just terminates, terminating your ssh session which will make the remote sshd kill the spawned nohup tcpdump proc. That why you end up with no tcpdump process.

这是您可以做的:

由于exec_command将为您的命令生成一个新线程,因此您可以将其保持打开状态并继续执行其他任务.但是请确保不时清空缓冲区(用于冗长的远程命令),以防止paramiko停顿.

Since exec_command is going to spawn a new thread for your command, you can just leave it open and proceed with other tasks. But make sure to empty buffers every now and then (for verbose remote commands) to prevent paramiko from stalling.

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username=login, password=password)
transport = ssh.get_transport()
channel_tcpdump = transport.open_session()
channel_tcpdump.get_pty()
channel_tcpdump.set_combine_stderr(True)

cmd = "tcpdump -i eth1  port 443 -w /tmp/dump20150317183305940107.pcap"        # command will never exit
channel_tcpdump.exec_command(cmd)  # will return instantly due to new thread being spawned.
# do something else
time.sleep(15)      # wait 15 seconds
_,stdout,_ = ssh.exec_command("pgrep tcpdump") # or explicitly pkill tcpdump
print stdout.read()     # other command, different shell
channel_tcpdump.close()     # close channel and let remote side terminate your proc.
time.sleep(10)

这篇关于如果进程是通过paramiko ssh会话并使用“&"来运行的,则进程终止.到底的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆