I'm trying to run the following:

$ tcpdump -l -X -i eth1 -n tcp port <port> | tee capture.txt | \
       scp capture.txt  [email protected]:/home/checker/
  1. tcpdump -l -X -i eth1 -n tcp port <port>

    In step #1 I'm capturing packets, using "-l" to to make standard out line-buffered, so that it will write each packet as it arrives.

  2. tee capture.txt

    In step #2 man tee: "The tee utility copies standard input to standard output, making a copy in zero or more files." The output is unbuffered.

  3. scp capture.txt root@<remote-IP>:/home/

    In step #3 I'm send the capture.txt file to a remote host.

The problem

If I simply perform steps #1 and #2, ALL packets are captured on the specified port. However, if I also use step #3 the capture.txt does NOT contain all the packets (only a few)... This is killing me because I had this running OK just a few minutes ago!

What is wrong here?

3 Answers 3


The tee command writes data to the output file as it receives it, but scp copies the file immediately and only copies it once. Since every command in the pipeline runs simultaneously (or nearly so), you only get a few (or no) packets output to the capture.txt file before the file gets copied by scp.

There are a couple ways to do what you seem to want to do.

If you want to copy a few packets from tcpdump, and then transfer the file to the remote host after it finishes, you can use the -c option to terminate tcpdump after it captures that number of packets. Separate your scp command from the pipeline using a semi colon so it gets executed after the tcpdump and tee commands complete:

tcpdump -l -c 10  | tee  /tmp/capture.txt; scp /tmp/capture.txt root@remotehost:/tmp

Or, if you want to see packets in real-time and also copy them in realtime, you could use tee to output the packets to /dev/tty so you can see them, and them pipe them into an ssh command that writes them to a file on the remote host:

tcpdump -l   | tee /dev/tty | ssh root@remotehost "cat > /tmp/capture.txt"

Note that without the -c option here, tcpdump will run until you kill it.

If you wanted the packets stored in a local capture.txt file as well as the remote, you could use multiple tee commands:

tcpdump -l   | tee /tmp/capture.txt | tee /dev/tty | ssh root@remotehost "cat > /tmp/capture.txt"
  • I've just noticed an issue. The capute.txt file that is sent to the remote host, on a second run of the tcpdump, is incremented instead of replaced... How do I overcome this? Oct 24, 2013 at 1:06
  • I'm not sure which of the command lines I provided you're using, but none of them should be appending to the file. "tee" will overwrite the output file with each run, and the ">" operator will also overwrite the file. Can you give more details? Are you running on Linux?
    – Johnny
    Oct 24, 2013 at 1:35
  • Yes, I'm running Debian Linux. I'm using: tcpdump -l | tee /dev/tty | ssh root@remotehost "cat > /tmp/capture.txt" I've tried to "echo /dev/null > capture" and "rm" the capture.txt but none of these are working =\ The file on the remote host keeps incrementing... Oct 24, 2013 at 2:17
  • Is it possible that you have one of the commands running in the background or in another terminal window?
    – Johnny
    Oct 24, 2013 at 2:26
  • nope =\ I'm trying to "fix" this with something like this: cat > /home/checker/temp.txt | cp /home/checker/temp.txt /home/checker/capture.txt | echo "" /home/checker/temp.txt The last part is to make sure the temp.txt is erased and, on the next tcpdump iteration, it is not incremented but instead written as a brand new file. But so far, this is not working (guess the cp is not working properly). Any ideias to copy a file's content into another? Oct 24, 2013 at 2:43

It is not guaranteed that tee finished writing capture.txt when scp reads it. What you could do is use the stdout of tee and pipe it through ssh like this:

tcpdump -l -X -i eth1 -n tcp port <port> | tee capture.txt | \
  ssh [email protected] 'cat > /home/checker/capture.txt'
  • Thaks a lot! It worked! :D Oct 23, 2013 at 21:49

I think the problem here is that the file you're copying via scp is copied at a moment in time and not continuously, so you end up with a fragment of the contents of that file on server

Try this instead:

$ sudo tcpdump -l -X -i eth1 -n <tcp port> | tee capture.txt | \
    ssh [email protected] 'cat > /home/checker/capture.txt

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .