2

I would like to start a tcpdump in my own script an after some time I would like to kill it again. How can I access the PID from the tcpdump. I tried it with $$ , but this only kills the script.

if [[ $TIMEEND != $Zeit ]];then
                        echo "tcpdump started"
                        sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
                        pid1=$!
                        break
                        #sudo umount /dev/sdb1
                else
                        sudo kill $pid1
                        echo "autodump stopped"
                fi

This is the output when i grep tcpdump so I think it's not possible to use pidof and pkill.

enter image description here

I tried to do it with awk

  pid1=$(ps -eo pid,args|awk '/abfrage2/ && ! /awk/{print $1}')
                            echo $pid1 >> /tmp/test.txt
                            sudo kill $pid1

When i directly use the command for pid, it finds the pid but it doesn't execute the kill.

I think I have to overthink my code a little bit. I inmport the time from the config file, then I check if the starttime is the same and if it is it should also check if it isn't the endtime. Then it should execute the tcpdump as long as it isn't the endtime. When it arrives the endtime it should kill the the tcpdump. I know it's not the best solution, but it would be nice to get it working with something like that.

   #!/bin/sh
source /media/usbhd-sdb1/config.conf
pluggedin=true
echo $TIMESTART
echo $TIMEEND
echo $$
echo $Zeit
echo $$ >> /tmp/test.txt
while [ $pluggedin ];do
        Zeit=$(date +"%T")
        if [[ $TIMESTART == $Zeit ]];then
                if [[ $TIMEEND != $Zeit ]];then
                        echo "tcpdump started"
                        sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
                        #sudo umount /dev/sdb1
                else
                        pid1=$(ps -eo pid,args|awk '/abfrage2/ && ! /awk/{print $1}')
                        echo $pid1 >> /tmp/test.txt
                        sudo kill -9 $pid1
                        echo "autodump stopped"
                fi

        else
        echo "tcpdump not yet started"
        fi
done
1
  • If you know in advance how long you want the tcpdump to run for you should consider the timeout command which will do what you want without you having to try to reinvent it all Commented Nov 30, 2015 at 14:13

3 Answers 3

3

If i understand you want to run the tcpdump for some time and kill it. You can do the following:

#!/bin/bash
sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &
PID=$!
sleep 20
sudo kill -9 $PID
exit 0

The $! will give you the pid of the command launched. To kill it you invoke the kill [Signal] [PID] to kill the tcpdump command.

Kindly note that we run the tcpdump in background with the & at the end of the command else the tcpdump will continue executing in the foreground. The exit 0 will ensure that the script is killed at the end.

[Proof of concept]

bash -x a.sh
+ PID=21988
+ sleep 10
+ tcpdump -i eth0 -w abfrage2.pcap
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
+ kill -9 21988
+ exit 0

[Alternatively]

As suggested by Eric you can also do it with timeout command

#!/bin/bash
timeout 10s tcpdump -i eth0 -w abfrage2.pcap
exit 0
2
  • Why is the answer down voted? Commented Nov 30, 2015 at 12:56
  • 1
    If you know you want to run for a fixed period the timeout command will do a lot of the work for you, and will exit before the timeout period if the command exits earlier than that, unlike sleeping for a fixed period Commented Nov 30, 2015 at 14:16
1

Your sudo tcpdump command should go into the background by appending an ampersand & to the line:

sudo tcpdump -i eth0 -w /media/usbhd-sd[b-c]1/abfrage2.pcap &

The line pid1=$! will put the PID of the sudo tcpdump command into variable pid1

If you want to kill the process you should use:

sudo kill $pid1

You used $$ which represents the PID of the current running process.

Since you are using this within another script, which you probably will call multiple times, all subsequential runs does not have a utilized pid1 variable.

To get the PID in this variable you can use:

pid1=$(pidof tcpdump)

in the else section of your script.

Or simply use:

sudo pkill tcpdump

Assuming that you only have one copy of tcpdump running.

One other thing you need to take care off. Every time you call your script and the $TIMEEND does not equals to $Zeit it will start another tcpdump process. A better solution would be:

if [ "$TIMEEND" != "$Zeit" ] && [ "$(pidof tcpdump)" == "" ]

which will test both the time requirement and the existence of a tcpdump process.

13
  • So I tried this, but it does terminate the script above and it also doesn't kill the tcpdump. What also could be important is that it is used in a if-else clause--> check updated post
    – apuboard
    Commented Nov 30, 2015 at 12:56
  • Do not downvote answers if the correct question is not asked... See updated answer to clarify what is problably wrong.
    – Lambert
    Commented Nov 30, 2015 at 13:04
  • I didn't downvote anything. I'm thankful for every help.
    – apuboard
    Commented Nov 30, 2015 at 13:06
  • @Lambert Totally agree !! @ apuboard did you run the script since both mine and Lambert suggestion works :) Kindly check the update. Besides, please do not modify your original codes in the question, please do it whithin an update secion. Commented Nov 30, 2015 at 13:06
  • @apuboard, apologies for my assumption then. nevertheless, see the updated answer for a probable cause.
    – Lambert
    Commented Nov 30, 2015 at 13:07
0

Variable values are not kept between different invocation of the same script. Meaning, you can't save your program PID in a variable and expect the variable to be initialized to that value when you run the script again.

Save the PID value in a temporary file:

if [...] ; then
    sudo tcpdump -i eth0 ..... &
    disown
    echo $! > somefile.pid
    echo "started"
else
    cat somefile.pid | xargs -n 1 kill
    echo "stopped"
fi

note that this command saves the sudo PID, not the tcpdump pid, which mean that you don't need sudo again to kill it

Also if you want a command in background to last more than the shell executing the script you should disown it right after launching

You must log in to answer this question.

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