Ввод цикла while должен поступать с выхода команды `command`

#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  

Следующие действия не работают.

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

Слишком мало результатов в Google (не понимаю, что я хочу найти:(). Я хотел бы сохранить совместимость с Bourne (/bin/sh), но это не обязательно.

Ответ 1

for line in $(tcpdump -n -r $pcap)  
do  
 command  
done 

Это не совсем то, что мне нужно. Но это близко. И совместимость с Shell. Я создаю таблицы HTML из вывода tcpdump. Цикл for создает новый <tr> строка для каждого слова. Он должен сделать новую строку для каждой строки (\n заканчивается). Вставить bin script01.sh.

Ответ 2

Это работает в bash:

while read line; do  
  ARRAY[$c]="$line"
  c=$((c+1))  
done < <(tcpdump -n -r "$pcap")

Ответ 3

Это sh -compatible:

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

Однако sh не имеет массивов, поэтому вы не можете использовать свой код в sh. Другие верны, говоря, что как bash, так и perl в настоящее время довольно распространены, и вы можете в основном рассчитывать на их доступность на не древних системах.

UPDATE, чтобы отразить комментарий @Dennis

Ответ 4

Если вы не заботитесь о том, чтобы быть bourne, вы можете переключиться на 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++] = $_;
}

Или в оболочке используйте for:

for line in $(tcpdump -n -r $pcap)  
do  
 command  
done