【问题标题】:Process dies, if it is run via paramiko ssh session and with "&" in the end进程死亡,如果它通过 paramiko ssh 会话运行并且最后带有“&”
【发布时间】:2015-05-20 05:34:16
【问题描述】:

我只想使用 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" &'

【问题讨论】:

    标签: python linux ssh paramiko tcpdump


    【解决方案1】:

    使用&,您可以立即退出远程命令。因此,远程 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)
    

    【讨论】:

      【解决方案2】:

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

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

      改成

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

      【讨论】:

      • 这不起作用。它在任何操作系统上都对你有用吗?在哪个?
      猜你喜欢
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多