Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

cmd timeout

by pronini (Initiate)
on Apr 07, 2010 at 10:46 UTC ( #833251=perlquestion: print w/replies, xml ) Need Help??
pronini has asked for the wisdom of the Perl Monks concerning the following question:

I need a script, that will run tcpdump with timeout and then exit. Here is what i have.
#!/usr/bin/perl use strict; my $pid = 0; my $cmd = $ARGV[0]; eval { my $process; local $SIG{ALRM} = sub { kill 'INT', $pid; close $process; die "ti +meout\n" }; alarm( 5 ); $pid = open $process, "$cmd |"; while (<$process>) { chomp ($_); print $_, "\n"; } };
usage: perl timeout 'tcpdump -n -i em0' It works perfectly. Runs tcpdump command and kills the perl script and tcpdump after 5 seconds. The main problem is buffering. When i have not a lot of captured packets, script doesn't show them. Could u please help me with that? I tried to do
select $process; $|=1; select $process;
doesn't help.

Replies are listed 'Best First'.
Re: cmd timeout
by ww (Archbishop) on Apr 07, 2010 at 10:53 UTC
      FWIW tcpdump can make its stdout line buffered. Check out the '-l' (ell) option.
        Thanks. -l did the thing.

      The problem with this kind of stuff (such as nc host port | tr foo bar) is usually that the first program (the one you read from) will buffer output if the stdout isn't a terminal, and you can do nothing about that without changing that program. Just changing the second program isn't enough. I don't know tcpdump so I can't tell if that's the problem here too though.

        There might be a command line option to make tcpdump output non-buffered. Looking at the man page, -U (packet-buffered) looks promising. Alternatively, take a look at -c (exit after receiving count packets) and -G (rotates the dump file specified with the -w option every rotate_seconds second).

        I would also like to point out that there's a good Perl module for Pcap, which is what tcpdump is built around: Net::Pcap.

        I agree, so I would change the signal handler to something like this:
        sub { kill 'INT', $pid; sleep 1; # Yield the CPU close $process; die "timeout\n" };
        You might need to give the process chance to flush its buffers. I know, a sleep is usually a sign of a suspcious hack.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://833251]
Approved by ww
Front-paged by ww
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2017-10-23 03:08 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (276 votes). Check out past polls.