进程死亡,如果它通过paramiko ssh会话运行,并在最后与“&”

我只是想使用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运行正常,但我的sshshell被阻止。

我如何正确地在后台运行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()只会阻塞,直到& ooperation的退出代码准备就绪。 你的代码然后终止,终止你的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)