0

I am trying to create a script in which I have:

tcpdump (options) | fgrep (options) > file

After I terminate tcpdump with CTRL+C I want these commands to execute:

sed (options) file | awk (options)
wait
rm file

The first part is getting done but after I press CTRL+C I get thrown to the prompt. I tried with wait, with trap SIGINT, same problem.

Now to get the obvious out of the way: why not simply pipe everything without dumping intermediary unfiltered output to a temporary file? Well I tried that but it seems the information is getting lost in my screen output (busy server, don't know) and I found that breaking the commands like this will allow me to have full output.

UPDATE: Based on the answers I got below, I tried doing it like this, it seemed to be the safest way to make it work:

function1 ()
{
tcpdump (options) | fgrep (options) > file
trap "function2" SIGINT SIGTERM
}

function2 ()
{
sed (options) file | awk (options)
wait
rm -i file
}

It doesn't work. "file" is generated but its content doesn't seem to be read and filtered by the sed | awk syntax after I do CTRL+C and it is not even being deleted by rm command so this is further proof that the secondary, trapped function is not being executed. I don't understand this behavior, am I doing something wrong?

UPDATE 2: The only way I could get it to work properly was like this:

set -m

tcpdump (options) | fgrep (options) > filename &

trap "kill -9 $!" SIGINT

sed (options) filename | mawk (options)

\rm filename

But I could not suppress the output from killing the background process, tried all the solutions I could find: Running bash commands in the background without printing job and process ids - this one makes my trap non-functional; With Bash Scripting, how can I suppress all output from a command? - all the variants from here do not work, I still get output no matter what I do. Tried defining the $! with another variable, tried all variants for /dev/null, tried placing it within the trap command, no use.

Community
  • 1
  • 1
one-liner
  • 791
  • 1
  • 9
  • 19

1 Answers1

0

Would it work for you to start the tcpdump command in the background and terminate it after a fixed amount of time? E.g. run

(tcpdump (options) | fgrep (options) > file) & 

then get the pid of the process and wait some time,

pid=$! 
sleep 60

and finally kill the command and parse the output

kill -9 $pid
sed (options) file | awk (options)
rm file

Update

If you really want Ctrl-P to stop tcpdump, trap is the way to go. However, after the trapped command is executed, you will always end up at the shell! So the behavior you described is actually what trap is supposed to do.

Thus you could write your trap command as

trap "{ sed (options) file | awk (options); rm file; }" SIGINT SIGTERM

and it should perform all the post-processing on interrupt. If you have more than these simple commands, it might make more sense to put all post-processing commands in a new script or function, e.g.

exec_on_interrupt() {
  sed (options) file | awk (options)
  rm file
  # other stuff...
}

trap "exec_on_interrupt" SIGINT SIGTERM
  • Unfortunately it is not possible to specify a defined amount of time for what I want to use this. Terminating tcpdump must be done by user via CTRL+C. – one-liner Dec 27 '13 at 03:47
  • Running in the background is not a bad idea... maybe you can do as @Michael suggests and have your bash script wait for some user input when you're ready to kill it ("Press q when you want tcpdump to stop...", and just sit there waiting). Capturing such input seems easier than forcing CTRL+C to mean "kill the tcpdump process but not this script". – James Dec 27 '13 at 14:34
  • I updated my question, unfortunately the provided solution doesn't seem to work as intended on my machine and I don't understand why. – one-liner Dec 28 '13 at 00:02
  • I finally got it working by using the first proposed solution and defined a key that when pressed will execute the kill -9 command for the PID. I still would have liked to use CTRL+C to terminate tcpdump. – one-liner Dec 28 '13 at 05:08