views:

48

answers:

4
#I used to have this, but I don't want to write to the disk
#
pcap="somefile.pcap"
tcpdump -n -r $pcap > all.txt
while read line; do  
  ARRAY[$c]="$line"
  c=$((c+1))  
done < all.txt  

The following fails to work.

# I would prefer something like...
#
pcap="somefile.pcap"
while read line; do  
  ARRAY[$c]="$line"
  c=$((c+1))  
done < $( tcpdump -n -r "$pcap" )

Too few results on Google (doesn't understand what I want to find :( ). I'd like to keep it Bourne-compatible (/bin/sh), but it doesn't have to be.

+2  A: 

If you don't care about being bourne, you can switch to Perl:

my $pcap="somefile.pcap";
my $counter = 0;
open(TCPDUMP,"tcpdump -n -r $pcap|") || die "Can not open pipe: $!\n";
while (<TCPDUMP>) {
    # At this point, $_ points to next line of output
    chomp; # Eat newline at the end
    $array[$counter++] = $_;
}

Or in shell, use for:

for line in $(tcpdump -n -r $pcap)  
do  
 command  
done  
DVK
In the shell version, you need to set IFS to a only a newline so that the output of `tcpdump` is not broken at each space.
Dennis Williamson
+2  A: 

This works in bash:

while read line; do  
  ARRAY[$c]="$line"
  c=$((c+1))  
done < <(tcpdump -n -r "$pcap")
Ignacio Vazquez-Abrams
Yes. It works in Bash. Any reason why it won't run in /bin/sh? I *would* like to make the script portable. Is portability usually important? To ensure others can also run the script...
Felipe Alvarez
The `<(...)` process substitution syntax is not available to sh.
Ignacio Vazquez-Abrams
Arrays are also not available to sh. But +1 for the process substitution.
Dennis Williamson
@DW. Didn't know array's aren't supported in `sh`. That doesn't bode well.
Felipe Alvarez
+1  A: 
for line in $(tcpdump -n -r $pcap)  
do  
 command  
done 

This isn't exactly doing what I need. But it is close. And Shell compatible. I'm creating HTML tables from the tcpdump output. The for loop makes a new <tr> row for each word. It should make a new row for each line (\n ending). Paste bin script01.sh.

Felipe Alvarez
You'll need to do `saveIFS=$IFS; IFS=$'\n'; your-for-loop; IFS=$saveIFS` since `IFS` causes things to be broken on spaces, tabs and newlines by default.
Dennis Williamson
I'll try it today and report back.
Felipe Alvarez
+3  A: 

This is sh-compatible:

tcpdump -n -r "$pcap" | while read line; do  
  # something
done

However, sh does not have arrays, so you can't have your code like it is in sh. Others are correct in saying both bash and perl are nowadays rather widespread, and you can mostly count on their being available on non-ancient systems.

UPDATE to reflect @Dennis's comment

Amadan
I had high hopes for this one, but it doesn't generate the HTML files! I can't understand why. >>http://stackoverflow.pastebin.com/TecWxMwW
Felipe Alvarez
eek, I left an "echo" inside, that I used for testing. Fixed now, should be equivalent to yours. (BTW, I assume you meant your code does not generate HTML when you insert this snippet - this snippet by itself doesn't generate HTML any more than your snippet did)
Amadan
Except that the Bourne shell doesn't have arrays. And, in Bash the two lines in the body of your loop (OK, the OP's loop) can be collapsed into: `ARRAY[$c]+=("$line")` or `ARRAY[c++]="$line"`. But +1 for the pipe into `while`.
Dennis Williamson
@Dennis: :) true... I was just thinking about the pipe...
Amadan
@Amadan - see http://stackoverflow.pastebin.com/TecWxMwW
Felipe Alvarez