I just want to run tcpdump
in background using paramiko.
Here is the part of the code:
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()
After I execute this code, pgrep tcpdump
returns nothing.
If I remove &
sign tcpdump
runs correctly, but my ssh shell is blocked.
How can I run tcpdump
in background correctly?
What command I've tried:
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" &'
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.
Here's what you can do:
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)