Page 3 of 3 FirstFirst 123
Results 21 to 29 of 29

Thread: Is there any way to grep a port range in netstat

  1. #21
    Join Date
    Sep 2009
    Location
    California U.S.A.
    Beans
    398

    Re: Is there any way to grep a port range in netstat

    O.K. So if I run
    Code:
    #! /bin/bash
    
    seq 1 10 | sed "s/^/ -e ':/" | sed "s/$/'/" ;bash
    
    
    
    exit
    It will give me

    Code:
     -e ':1'
     -e ':2'
     -e ':3'
     -e ':4'
     -e ':5'
     -e ':6'
     -e ':7'
     -e ':8'
     -e ':9'
     -e ':10'
    So now the problem I have is that each one is a new line. So what I need to do is instead of a new line I need them just separated by spaces. Let me know what you think.

  2. #22
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Is there any way to grep a port range in netstat

    Code:
    echo {a..z} {1..10}
    echo -e\ {1..10}
    echo -e\ :{8000..9000}[^0-9]*
    
    netstat --tcp --numeric | awk 'NR>2 {print $5}' | grep $( echo -e\ :{8000..9000}[^0-9]* )
    that command takes approx 1sec/1k of ports on my box - i thought it would be worse. Still i don't like it 3/4 of the time is probably spent on the optimization of the expression alone as the results start to flow near the end.
    approach of my script may be a bit slower than pure grepping for smaller sets of ports (who cares about 0.2s vs 1s anyway), it wins hands down in flexibility and in cases with huge port ranges where the execution time of naive grep reaches 30+ secs

    btw, you can flatten multiline text simply by echoing it or storing in a variable
    Code:
    seq 1 10
    echo $(seq 1 10)
    var=$(seq 1 10)
    echo $var
    you can change this behavior by playing with the IFS variable that defines the separator of 'words'. By default any whitespace is considered a separator and is changed into space when you run it through variables and commands. You can change it so let's say only newlines are separators (=> formatting doesn't degrade). Very useful when you got to do something with let's say files with spaces in names, changing IFS to newline only prevents filename fragmentation that leads to frequent errors.
    Last edited by Vaphell; January 18th, 2011 at 02:25 PM.

  3. #23
    Join Date
    Sep 2009
    Location
    California U.S.A.
    Beans
    398

    Re: Is there any way to grep a port range in netstat

    Alright heres what I got. This

    Code:
    seq 1 10 | sed "s/^/ -e ':/" | sed "s/$/ '/" | tr "\\n" " "
    Will give me the range all on one line.

    I tried the code you just posted

    Code:
    echo {a..z} {1..10}
    echo -e\ {1..10}
    echo -e\ :{8000..9000}[^0-9]*
    
    netstat --tcp --numeric | awk 'NR>2 {print $5}' | grep $( echo -e\ :{8000..9000}[^0-9]* )
    and it gave me

    Code:
    -e :8000[^0-9]* -e :8001[^0-9]* -e :8002[^0-9]* -e :8003[^0-9]* -e :8004[^0-9]* -e :8005[^0-9]* -e :8006[^0-9]* -e :8007[^0-9]* -e :8008[^0-9]*  etc etc..
    So now I come to the other part. The if then. My script goes like this

    Code:
    if [ "$(netstat --tcp --numeric |  cut -c 45-65 | sort -u | sed '/Foreign/d' | sed '/^$/d' | grep -e ':80' -e ':443')" ]; then
    echo 'http / https' && netstat --tcp --numeric |  cut -c 45-65 | sort -u | sed '/Foreign/d' | sed '/^$/d' | grep  -e ':80' -e ':443'
    fi
    So, the if has to contain the whole statement so that the http / https will only echo if there is output from the original statement. Is there a better way?

  4. #24
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Is there any way to grep a port range in netstat

    I tried the code you just posted
    my example code showed how to produce a range of parameters. I merely printed out that huge range of -e '...' with the intermediate steps like using {..} to easily construct a range. Last line *should* do what you want as it actually uses that bunch of generated parameters in grep.

    So now I come to the other part. The if then. My script goes like this
    1. why do you still use that cut | sort | sed | sed combo?
    awk 'NR>2 { print $5 }' will print out the 5th element of each row when the row number > 2 (skips Foreign and empty line automatically), so you don't have to cut from-to and then remove non-ip lines with sed manually - unless i am missing something

    2. you should sort after grepping - picking 10 elements out of 100 and sorting them later is more efficient than sorting 100 elements and picking 10 later. Doesn't matter much in a case with not so many lines but if you ever wanted to do that on a huge set of data, it would be like a night and day.

    3. you execute the chain twice for no good reason
    store the result in a variable, check the variable, print the variable out if the condition is met

    PHP Code:
    #!/bin/bash

    fixed="-e .*:80 -e .*:443"
    range=$( echo '-e .*:'{8000..8090} )
    ports=$( echo "$fixed" "$range)

    grepped=$( netstat --tcp --numeric awk 'NR>2 {print $5}' grep -w $ports sort -)

    if [ 
    "$grepped]; then
      
    echo == HTTP/HTTPS ==
      echo 
    "$grepped"
    fi 
    Last edited by Vaphell; January 20th, 2011 at 04:09 AM.

  5. #25
    Join Date
    Sep 2009
    Location
    California U.S.A.
    Beans
    398

    Re: Is there any way to grep a port range in netstat

    Quote Originally Posted by Vaphell View Post



    why do you still use that cut | sort | sed | sed combo?
    awk 'NR>2 { print $5 }' will print out the 5th element of each row when the row number > 2 (skips Foreign and empty line automatically), so you don't have to cut from-to and then remove non-ip lines with sed manually - unless i am missing something
    No, it was me who was missing something. I just don't completely understand the command. What you said was that {print $5} prints the fifth element. That makes sense to me. But what does NR>2 mean? I know you explained it but I still do not completely get it. I just tried it and it works great though.



    you execute the chain twice for no good reason
    store the result in a variable, check the variable, print the variable out if the condition is met
    I did not know that a variable could be a command. That makes things alot easier. So, is it always

    variable=$( yourcommandhere )

    I tried it before but did not use a $ and it did not work. I still have much to learn.


    Code:
    fixed="-e .*:80 -e .*:443"
    range=$( echo "-e"\ '.*:'{8000..8090} )
    ports=$( echo "$fixed" "$range" )
    
    grepped=$( netstat --tcp --numeric | awk 'NR>2 {print $5}' | grep -w $ports | sort -u )
    
    if [ "$grepped" ]; then
      echo == HTTP/HTTPS ==
      echo "$grepped"
    fi
    After playing with this for a minute I think you have got it! This is it. The answer to the whole problem. I feel like you have been trying to show this to me for a while and I just did not get it. Also, with some very minor tweaking, I can use either one of the variables to get the desired effect. Dependant upon whether I want a range or a fixed number of ports. I can't believe I did not see this before. This is going to save me a lot of work and space. I have learned much from you. This is why I like ubuntu forums. Thank you.

  6. #26
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Is there any way to grep a port range in netstat

    let's take few lines of the netstat output
    Code:
    Active Internet connections (w/o servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State      
    tcp        0      0 10.111.255.23:42631     10.111.12.74:22        ESTABLISHED
    as you can see first 2 lines are junk, we don't need them
    Code:
    awk 'NR>2 { print $5 }'
    bolded part is a condition: do the stuff in {} only when the row number (NR) is greater than 2

    we need only foreign ip:port and it's is in the 5th column
    Code:
    awk 'NR>2 { print $5 }'
    bolded part: print 5th column of the data row

    combined it means 'skip first 2 rows and then print the 5th thing from each row'
    Last edited by Vaphell; January 20th, 2011 at 06:45 AM.

  7. #27
    Join Date
    Sep 2009
    Location
    California U.S.A.
    Beans
    398

    Re: Is there any way to grep a port range in netstat

    Quote Originally Posted by Vaphell View Post
    Code:
    awk 'NR>2 { print $5 }'
    bolded part is a condition: do the stuff in {} only when the row number (NR) is greater than 2

    we need only foreign iport and it's is in the 5th column
    Code:
    awk 'NR>2 { print $5 }'
    bolded part: print 5th column of the data row

    combined it means 'skip first 2 rows and then print the 5th thing from each row'
    Thank you for the explanation. One last question before I mark this thread as solved. NR>2 chops off the first two lines. I got that. But when I reverse it like NR<2 it only shows me the first line. How would I go about chopping off just the last 2 lines?

  8. #28
    Join Date
    Jul 2007
    Location
    Poland
    Beans
    4,499
    Distro
    Ubuntu 14.04 Trusty Tahr

    Re: Is there any way to grep a port range in netstat

    well, it's rather obvious
    the opposite of 'greater than' is not 'less than' but 'less than or equal'

    #1: (1>2) -> false (1<2) -> true
    #2: (2>2) -> false (2<2) -> false
    #3: (3>2) -> true ( 3<2) -> false

    you need to use <= or >= operators to include the boundary

  9. #29
    Join Date
    Sep 2009
    Location
    California U.S.A.
    Beans
    398

    Re: Is there any way to grep a port range in netstat

    Thanks again. Marking this thread as solved.

Page 3 of 3 FirstFirst 123

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •