如果通过paramiko ssh会话和“&”运行,则进程死亡到底

时间:2015-03-17 16:51:12

标签: python linux ssh paramiko tcpdump

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

以下是代码的一部分:

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不返回任何内容。

如果我删除&符号tcpdump正确运行,但我的ssh shell被阻止。

如何正确地在后台运行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" &'

2 个答案:

答案 0 :(得分:3)

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

以下是您可以做的事情:

由于exec_command将为您的命令生成一个新线程,您可以将其保持打开状态并继续执行其他任务。但请确保不时地清空缓冲区(对于详细的远程命令)以防止paramiko停止。

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)

答案 1 :(得分:1)

只需要添加一个睡眠命令,

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

更改为

cmd = "(nohup tcpdump -i eth1  port 443 -w /tmp/dump20150317183305940107.pcap) &; sleep 1"