OK. I see.
I thought you wanted a script that would start tcpdump and then end it at a specified time.
But what you really want is something to get the PID of an already running tcpdump and kill it at a specified date/time. Is that correct?
There are multiple problems with the script you've posted.
- Line 4 - there is a space between $ and ( - that space should not be there
- Line 4 - the -x switch to grep will match the regex against the whole line.
In other words the whole line output from ps would have to exactly match '[p]ing'. So you'd get no matches from that, because the line from ps would be a lot longer!
- Line 4 - missing ) at the end of the line
- Line 6 - all you need here is "kill -15 $pid". The rest of the line is not needed.
- Line 7 - I don't know what you are trying to do here. Is the = supposed to be a test for equality? Or an assignment? If it's an assignment, there should be no spaces between the two operands either way the whole line is nonsense from a syntactical point of view!
If we are dealing with an already running instance of tcpdump, then you could use a script like this:
Code:
#!/usr/bin/env bash
pid=$(ps -ef | \grep tcpdump | \grep -v grep | awk '{print $2}'
if [[ $pid ]]; then
kill -15 $pid
fi
And set it up as a cron job to run at the specified date/time. That would definitely be a way to kill an existing process at a specified date and time.
NOTE: Regarding my usage of grep in the above.
The reason I'm using \grep is in case you have any aliases set up for grep.
I often have grep aliased to "grep=grep -n --color" in my .bashrc. which colourizes the output from grep and prints the line number at the beginning of the output for matched lines.
So I use \grep to escape any aliases and just use grep without any fancy formatting options. This ensures that grep doesn't add any additional fields to matching lines in the output from ps.
Also, the reason I've used two grep commands is because in the following ps command (with one \grep):
Code:
ps -ef | \grep tcpdump | awk '{print $2}'
In the output from the ps command - \grep would match the line containing the tcpdump process that we are interested in AND the line containing the process running the "ps -ef | \grep tcpdump | awk '{print $2}'" command - because it also contains "tcpdump".
So awk would then populate $pid with two pids.
The kill command afterwards would sucessfully kill the tcpdump process, but when it tries to kill the process that was running "ps -ef | blah blah blah" - kill will complain about trying to kill a non-existent process, because at that point the process running the "ps...." command would have already ended.
So the 2nd \grep filters out the "ps -ef | blah blah blah" line - preventing it's PID from being added to $pid and preventing an error message from kill.
One final consideration - if you have multiple tcpdump commands running, the above script would end up killing ALL running tcpdump processes.
If that is the case, and you only want to end ONE particular instance of tcpdump - you would need to another call to \grep to narrow in on the exact process you are looking for - based on some unique criteria that will identify it from the others.
e.g.
Perhaps it is the only one that is looking on wlan0 for udp packets? Or maybe the start-time of the process?
Either way - if there are several tcpdumps running - and you want to end a specific one - you will need to change the above script to \grep the output from ps for something that will uniquely identify the process you are after.
Hope this helps!
If you have any questions - fire away!