1

I am trying to check whether specific rules in IPTables exists or not.

#!/bin/bash

if iptables -L -n | grep -- "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880";
 then
     echo "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880 exists"
 else
     echo "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880 does not exist"
fi

if iptables -L -n | grep -- "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80";
 then
     echo "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 exists"
 else
     echo "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 does not exist"
fi

I am checking below two rules:

ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880

ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80

Because those two rules already exists and conditions run the TRUE case, terminal also outputs the result of the grep in conditional check unnecessarily. grep somehow does not output for FALSE case.

How can I prevent the grep to output for TRUE case?

And how can I combine those separate two if conditionals into a single OR conditional?

BTW, my IPTables is old version and can not use -C argument.

1

The default action of grep is to print the matching line. To suppress that, you can use grep -q:

#!/bin/bash

if iptables -L -n | grep -q -- "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880";
 then
     echo "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880 exists"
 else
     echo "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880 does not exist"
fi

if iptables -L -n | grep -q -- "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80";
 then
     echo "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 exists"
 else
     echo "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 does not exist"
fi

You could also simplify your script to this:

#!/bin/bash

rules=( "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880"  "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80")


for rule in "${rules[@]}"
do
    iptables -L -n | grep -q "$rule" && echo "$rule exists" || echo "$rule does not exist"
done

Or, if you want to have multiple actions, use an if/else like so:

#!/bin/bash

rules=( "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8880"  "ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80")


for rule in "${rules[@]}"
do
    if iptables -L -n | grep -q "$rule"
    then
        echo "$rule exists"
    else
        echo "$rule does not exist"
    fi
done
| improve this answer | |
  • Thanks @terdon, I will accept your question. Would you mind posting the code for "If one (or both) of these rules does not exist, echo the non-existent rule and do something"? I am trying to to check if there http rules exist or not, if not I will try to reload the iptables into default state. So it would be great to have double conditional but one block code to execute. – NecNecco Sep 21 '15 at 11:47
  • @NecNecco what do you mean? Both of the scripts above echo the rule and "does not exist" when the rule isn't present. – terdon Sep 21 '15 at 11:58
  • I mean if one of there rules does not exist or both of these rules does not exist, print the rule and reload the firewall. Currently for iterates two times. I am not sure where to put the code for firewall reloading. Sorry, new to bash scripting. I think just checking two rules with an OR and executing code in then section would do good. – NecNecco Sep 21 '15 at 12:12
  • @NecNecco see updated answer. Add the firewall code on a new line under the relevant echo. – terdon Sep 21 '15 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.