0

On Ubuntu OS, I'm trying to grab different input, do something with that input, but then output the variables in order. I thought this would be easy, but my searches are coming up nil.

The idea is to get a list of connected IP's and update the screen. I want to see the IP's, protocols and hostnames that are connecting to a server and show this list on screen live as it happens.

This is what I have so far, it doesn't look very pretty. Protocol prints all ports on one line.

#!/bin/bash
#
while true; do
clear
    #echo -e "Press Ctrl + c to quit \n"
    ip=$(netstat -natu | grep 'ESTABLISHED' | cut -d: -f2 | awk '{print$2}')
    prot=$(netstat -tu | grep 'ESTABLISHED' | cut -d: -f2 | awk '{print$1}')
    echo -e Protocol "\t" IP Address "\t" Name
    for n in $ip; do
        nbt=$(nbtscan $n | awk  '{print $2}' | tail -1)
        echo -e $prot "\t" $n "\t" $nbt #> connections.txt
    done

    sleep 2
done

Output shows

Protocol         IP Address      Name
ssh ftp          192.168.1.254   TIS-ADMIN02
ssh ftp          192.168.1.197   TRAINING2

it should show this

Protocol         IP Address      Name
ssh              192.168.1.254   ADMIN02
ftp              192.168.1.197   TRAINING2
  • 1
    please update the question to show the (wrong) output generated by your code and the (correct) expected output – markp-fuso Nov 30 '22 at 16:54
  • Note that `echo -e` is not good form -- depending on how your copy of bash is configured it can write `-e` on output instead of changing how escape sequences are configured. The POSIX `echo` specification recommends using printf instead anytime you might otherwise be using either backslash escapes or the `-n` argument with `echo`. – Charles Duffy Nov 30 '22 at 17:16
  • And even if you _do_ use `-e`, you should be quoting your expansions. `echo -e 'Protocol\tIP Address\tName'`, `echo -e "$prot\t$n\t$nbt"`, etc. With your old code, if `prot='*'`, you'd print a list of filenames in the current directory as part of your output. – Charles Duffy Nov 30 '22 at 17:16
  • as for the question you're _actually asking_, though... we have existing Q&A about "How do I iterate over two arrays in bash in lockstop?". You should be (1) storing your output in arrays, not strings; and (2) following that advice. – Charles Duffy Nov 30 '22 at 17:18
  • Or even... `while read -r prot ip _; do ...; done < <(netstat -natu | grep 'ESTABLISHED' | cut -d: -f2)` -- that way you also avoid bugs where the two `netstat` calls return different results because they're running at different points in time. – Charles Duffy Nov 30 '22 at 17:20
  • Thank you Charles, I'll give that a look over. – user20647503 Nov 30 '22 at 17:20
  • 1
    Probably also avoid parsing the output from `netstat` twice. Its output is system-dependent, but I'm guessing something like `netstat -natu | awk '/ESTABLISHED/ { split($4, n, ":"); print $5, n[2] }' | while read -r ip port; do` – tripleee Nov 30 '22 at 17:21
  • To read something to an array: `readarray -t prots < <(netstat -tu | grep 'ESTABLISHED' | cut -d: -f2 | awk '{print $1}')` will give you an array with all the protocol results. But again, I advise against that; better to only run netstat once so you don't need to worry about the two calls having different output (the list of established connections does change over time!) – Charles Duffy Nov 30 '22 at 17:21
  • 1
    Somewhat similarly, `awk '{ print $2 }' | tail` can be refactored to `awk 'END { print $2 }'`; Awk can do everything `grep` and `cut` and `tail` can do, and then some, so if you are using Awk anyway, you basically don't need those. – tripleee Nov 30 '22 at 17:23

0 Answers0