Like Tree3Likes

Awk and sed bash script help

This is a discussion on Awk and sed bash script help within the Linux Programming forums, part of the Platform Specific Boards category; I posted another thread on linuxquestion forums. LINK: ---> if else then trouble(bash) I am having scripting troubles. I am ...

  1. #1
    Registered User Annonymous's Avatar
    Join Date
    Apr 2011
    Location
    Jackson, New Jersey, United States
    Posts
    302

    Awk and sed bash script help

    I posted another thread on linuxquestion forums. LINK: ---> if else then trouble(bash) I am having scripting troubles. I am not knocking that forum because they are seriously awesome but cboard is so much more active!! Probably one of, if not the most active forum i have been on! So i decided to post my question here as well.

    I am trying to use awk, sed, and bash commands to parse netstat output and then if ports other than 443 or 80 are open display a UI i wrote. otherwise exit.

    UI code:
    Code:
    #include <gtk/gtk.h>
    
    static void destroy_event(GtkWidget *widget, gpointer data) {
    gtk_main_quit();
    }
    
    static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
    gtk_main_quit();
    return FALSE;
    }
    
    static void callback( GtkWidget *widget, gpointer data ) {
    gtk_main_quit();
    }
    
    //To compile append `pkg-config --cflags --libs gtk+-2.0`
    int main(int argc, char *argv[]) {
    
    GtkWidget *window;
    GtkWidget *table;
    GtkWidget *button;
    GtkWidget *frame;
    
    gtk_init(&argc, &argv);
    
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "SECURITY WARNING");
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
    gtk_widget_show(window);
    
    table = gtk_table_new(10, 10, TRUE);
    gtk_container_add(GTK_CONTAINER(window), table);
    gtk_widget_show(table);
    
    frame = gtk_frame_new("SUSPICIOUS PORT IS OPEN");
    gtk_table_attach_defaults(GTK_TABLE(table), frame, 1, 9, 2, 8);
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
    gtk_widget_show(frame);
    
    button = gtk_button_new_with_label("OK");
    gtk_table_attach_defaults(GTK_TABLE(table), button, 2, 8, 3, 7);
    gtk_widget_show(button);
    
      g_signal_connect_swapped(G_OBJECT(window), "destroy-event",
          G_CALLBACK(destroy_event), NULL);
    
      g_signal_connect_swapped(G_OBJECT(window), "delete-event",
          G_CALLBACK(delete_event), NULL);
    
      g_signal_connect (button, "clicked",
          G_CALLBACK (callback), (gpointer) "cool button");
    
    gtk_main();
    
    return 0;
    }
    The bash script:
    Code:
    #!/bin/bash
    
    netstat -ant | 
    awk -F" " '{print $5}' | 
    awk -F":" '{print $2}' > netstat.txt;
    sed '/^$/d' netstat.txt;
    
    PORTS="$(egrep -i "^80|443" /path/to/netstat.txt)"
    
    if [ "$PORTS" ]; then
    	 exit 0;
    
    		else 
    		sudo /path/to/ui_executable
    
    fi
    What i would like to achieve with the if statement is if the only ports open are 443 and 80, then exit. If "MORE" than 443 and 80 are open, display my UI.

    I cannot figure out how to achieve this. Ideas?

    Thanks!

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    With grep you're using -i (case insensitive) when you want -v (invert match).
    Code:
    PORTS=$(netstat -ant | awk -F" " '{print $5}' | awk -F":" '{print $2}' | sed '/^$/d' | grep -Ev "80|443")
    if [ "$PORTS" ] ; then echo yep ; else echo nope ; fi
    Or a little simpler
    Code:
    if [ "$(netstat -ant | awk '{print $5}' | grep -Eo ":[0-9]+" | grep -Ev ":80|:443")" ] ;
    then echo yep ;
    else echo nope ;
    fi
    Actually, that's not really any simpler.
    Last edited by oogabooga; 05-07-2012 at 11:58 PM.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User Annonymous's Avatar
    Join Date
    Apr 2011
    Location
    Jackson, New Jersey, United States
    Posts
    302
    Quote Originally Posted by oogabooga View Post
    With grep you're using -i (case insensitive) when you want -v (invert match).
    Code:
    PORTS=$(netstat -ant | awk -F" " '{print $5}' | awk -F":" '{print $2}' | sed '/^$/d' | grep -Ev "80|443")
    if [ "$PORTS" ] ; then echo yep ; else echo nope ; fi

    WOW, so much cleaner than the slop i put together. thanks.

    See the problem i am still having is that ports will always evaluate as true. As long as the net is open. Even if i have a torrent site up with high ports open, it will still be true.

    I am trying to launch the UI if an open port other than 443 or 80 is open.

    I figured, remove all duplicate ports. Remove the asterisk and blank lines. Then count the lines and if there are more than 2, then launch the UI.

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Can you give an example of your netstat -ant output?

    I'm not sure what you mean that PORTS will always be true?
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  5. #5
    Registered User Annonymous's Avatar
    Join Date
    Apr 2011
    Location
    Jackson, New Jersey, United States
    Posts
    302
    Well what i am saying is that if i use this:
    Code:
    root@blah:/path# PORTS=$(netstat -ant | awk -F" " '{print $5}' | awk -F":" '{print $2}' | sed '/^$/d' | grep -Ev "0|1|2|3|4|5|6|7|8|9"); if [ "$PORTS" ] ; then echo yep ; else echo nope ; fi
    yep
    root@blah:/path#
    i will always get the yep answer. PORT will always evaluate to true. Well unless the internet is not open.

    So what i am trying to accomplish is that if anything other than port 443 and/or 80 is open then display the UI warning. Otherwise, just exit. Ill have the script ran at start up and run every minute im guessing.


    I figured i could do something like this:
    Code:
    #!/bin/bash
    
    netstat -ant | awk -F" " '{print $5}' | awk -F":" '{print $2}' | sed '/^$/d' | egrep -E "[0..9]" > netstat.txt;
    #-v switch w/grep fam will remove specified.
    
    awk '!x[$0]++' netstat.txt > netstat2.txt && cat netstat2.txt | sed '/^$/d' netstat2.txt;
    LINES=`awk 'END {print NR}' netstat2.txt`;
    echo "Number of lines = $LINES"
    
    if [ $LINES > 3 ]; then
    echo "Greater than 3"
    
    	else #if [ $LINES < 3 ]; then 
    	echo "Less than 3"
    		
    	#fi
    
    fi

    But for some reason the script returns greater than 3 every time. Even if only port 80 is open.

    I HOPE I AM BEING CLEAR! If not please say so and i will try to better clarify my intention/statement. Thanks.
    Last edited by Annonymous; 05-08-2012 at 12:34 AM.

  6. #6
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Try this
    Code:
    CNT=$(netstat -ant | awk '{print $5}' | grep -Eo ":[0-9]+" | grep -Evc ":80|:443")
    if [ $CNT == 0 ] ; then echo nope ; else echo run program ; fi
    Annonymous likes this.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  7. #7
    Registered User Annonymous's Avatar
    Join Date
    Apr 2011
    Location
    Jackson, New Jersey, United States
    Posts
    302
    @oogabooga, that works. Thanks. If you would be so kind, could you explain your code? More specifically

    this
    Code:
    -Eo ":[0-9]+"
    and
    Code:
    -Evc ":80|:443"
    Thanks again.
    Last edited by Annonymous; 05-08-2012 at 12:44 AM.

  8. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    grep -E is the same as egrep (but I believe it's the preferred modern form).
    The o flag means only output the matching text instead of the whole line.
    v means invert output (output non-matching lines).
    c means count lines.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,640
    Are you sure you want to print column 5? That's the foreign address/port. If you're looking for what's open on your machine, you should print $4, at least, that's the way it appears on my netstat output.

    Also, try dropping the quotes from your test, or explicitly using the -n option in your test:
    Code:
    if [ $PORTS ]; ...
    # or
    if [ -n "$PORTS" ]; ...
    You can read up on subtleties of bash quoting, and in particular, with the test command, here: Quotes and escaping [Bash Hackers Wiki].

    EDIT: Another awesome bash reference: Advanced Bash-Scripting Guide.
    Last edited by anduril462; 05-08-2012 at 01:09 AM. Reason: Fixed second 'if' in example to use quotes
    Annonymous likes this.

  10. #10
    Registered User Annonymous's Avatar
    Join Date
    Apr 2011
    Location
    Jackson, New Jersey, United States
    Posts
    302
    @anduril462, with 4, yes I will see local ports. The problem with that is, they are all high ports and i wouldnt know the difference. Where as, if i use 5, i can see what ports i am connecting to. Like if i open facebook only, it will show port 443 open in the foreign field. Let's say I were to use 4, how would i know which to parse? Again, they are after all, high random ports.

    Correct me if I am wrong though.

    @oogabooga, i could just open a terminal and type in the command with the --help switch and it will explain all of that. I was actually talking about the extras that the man pages wouldn't explain. Like The : or the + sign. I will just google it. I appreciate the help you have already provided. I a grateful!
    Last edited by Annonymous; 05-08-2012 at 01:06 AM.

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,640
    Quote Originally Posted by Annonymous View Post
    @anduril462, with 4, yes I will see local ports. The problem with that is, they are all high ports and i wouldnt know the difference. Where as, if i use 5, i can see what ports i am connecting to. Like if i open facebook only, it will show port 443 open in the foreign field. Let's say I were to use 4, how would i know which to parse? Again, they are after all, high random ports.

    Correct me if I am wrong though.
    No, you're right. I was playing catch-up, and I guess I skimmed the thread a little too quickly .

  12. #12
    Registered User Annonymous's Avatar
    Join Date
    Apr 2011
    Location
    Jackson, New Jersey, United States
    Posts
    302
    So now could anyone tell me how i could get my script to produce the same results as @oogabooga's?

    Code:
    #!/bin/bash
    
    netstat -ant | awk -F" " '{print $5}' | awk -F":" '{print $2}' | sed '/^$/d' | egrep "0|1|2|3|4|5|6|7|8|9" > netstat.txt;
    #CNT=$(netstat -ant | awk '{print $5}' | grep -Eo ":[0-9]+" | grep -Evc ":80|:443")
    #-v switch w/grep fam will remove specified.
    
    LINES=$(awk '!x[$0]++' netstat.txt > netstat2.txt && cat netstat2.txt | sed '/^$/d' netstat2.txt | awk 'END {print NR}' netstat2.txt) 
    NLINES=`echo $LINES`;
    
    if [ $NLINES < 3 ]; then
    echo "Your safe"
    
    	else if [ $NLINES > 3 ]; then 
    	/home/codecaine21/Documents/warning
    		
    	fi
    
    fi
    No matter how i re-arrange the script, the result "always" prints your safe. Never runs the UI warning. Even if i have 73 different ports open.

    MY PROBLEM SEEMS TO COME FROM MY COMPARISON in my if statement. If i echo $LINES or $NLINES they will output the same number but when try to compare either variables to the number 3, it seems to make no difference.
    I even switched the conditions to the if statement around just to see if its behavior would change, it didn't. Which leads me believe that...well idk, I'm STUMPED!
    Last edited by Annonymous; 05-08-2012 at 02:32 AM.

  13. #13
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,640
    Try reading the links I gave you. The bash-hackers.org has a link to the test command near the bottom of the quoting page I liked you to that will explain your problem with using <. The Advanced Bash-Scripting guide has a whole section on tests that might explain why your code doesn't work. Heck, to save you time, it's section 7.3 of the ABS guide.

    Also, you may want to make sure you cover the case where $NLINES is exactly 3, and you should look up the elif command for a better "else if" construct that doesn't nest.
    Annonymous likes this.

  14. #14
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    i could just open a terminal and type in the command with the --help switch and it will explain all of that. I was actually talking about the extras that the man pages wouldn't explain. Like The : or the + sign. I will just google it.
    I know. I felt kind of silly posting that but I wasn't sure what you didn't understand.

    The : is simply a : (i.e., match a colon).
    The + means to match "one or more" of the previous item (it's a basic regex thing, which you could also google).

    Here's a GNU Grep 2.12 reference. It describes the switches and the regex's.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  15. #15
    Registered User Annonymous's Avatar
    Join Date
    Apr 2011
    Location
    Jackson, New Jersey, United States
    Posts
    302
    Quote Originally Posted by oogabooga View Post
    I know. I felt kind of silly posting that but I wasn't sure what you didn't understand.

    The : is simply a : (i.e., match a colon).
    The + means to match "one or more" of the previous item (it's a basic regex thing, which you could also google).

    Here's a GNU Grep 2.12 reference. It describes the switches and the regex's.
    @oogabooga, Don't feel silly. I have a tendency to post ambiguous questions! Just ask anyone, or better yet read some of the posts i have made here. I appreciate the responses and help you have provided though. Thank you!

    @Anduril, i will revisit the code in a little. I am downloading a movie from thepiratebay, so i will most likely have 20+ ports open. I have an idea as to why it is not properly working. I figure i need to use the -gt or -lt switches instead of the string comparison operator(> or <) i am using.

    We will see in a little while though. Thanks!

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help converting bash shell script to windows
    By chelp123 in forum Tech Board
    Replies: 2
    Last Post: 11-24-2011, 02:22 PM
  2. ssh/bash script question
    By Overworked_PhD in forum Tech Board
    Replies: 2
    Last Post: 03-30-2009, 08:48 PM
  3. Bash Script Q
    By QuestionC in forum Tech Board
    Replies: 1
    Last Post: 04-19-2007, 11:16 AM
  4. Linux: Use C to call a bash script
    By harada in forum Linux Programming
    Replies: 9
    Last Post: 10-27-2006, 02:59 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21