MLSC
MLSC

Reputation: 5972

Compare result of command with string in bash

I have a string and a command result so I want to compare them:

A="Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination"

B=$(iptables -L)

if [ "$A" == "$B"]; then
    echo "True"
else
    echo "False"
fi

But it returns False.

Upvotes: 1

Views: 477

Answers (3)

hek2mgl
hek2mgl

Reputation: 157927

It's due to the different amount of whitespace used. You can find that out using the following command:

diff -u <(iptables -L) - <<EOF | cat -A
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
EOF

Output:

--- /dev/fd/63^I2016-04-11 08:59:52.663962140 +0200$
+++ -^I2016-04-11 08:59:52.666667769 +0200$
@@ -1,8 +1,8 @@$
 Chain INPUT (policy ACCEPT)$
-target     prot opt source               destination         $
+target     prot opt source               destination$
 $
 Chain FORWARD (policy ACCEPT)$
-target     prot opt source               destination         $
+target     prot opt source               destination$
 $
 Chain OUTPUT (policy ACCEPT)$
-target     prot opt source               destination         $
+target     prot opt source               destination$

You see, the iptables -L command appends whitespace after destination.

To remove that whitespace, you can use sed:

iptables -L | sed 's/[[:space:]]*$//'

If you also fix the syntax error discovered by Jonathan Leffler, your code should work.

Let me add, that the way you are checking if "the firewall is not active" might be to weak. (a) you see, the iptables -L command is not really meant to be used for text processing. (b) somebody might have added a custom chain but no rules in it. This would let your check fail.

I don't have really an idea how to do it better. Probably changing firewall rules is meant to be a task executed by the administrator himself rather than by programs. :)

Upvotes: 3

riteshtch
riteshtch

Reputation: 8769

It doesnt match because of whitespaces at end in iptables -L

A=$(cat <<EOF
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
EOF
)
B="$(iptables -L)"

diff -Z <(echo "$A") <(iptables -L) && echo "True" || echo "False"

check this:

meld differences

btw invoked the meld command like this: meld <(echo "$A") <(iptables -L) (meld is a visual diff tool)

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 753455

Spacing!

Wrong:

if [ "$A" == "$B"]; then

Right:

if [ "$A" == "$B" ]; then

[ is a command; it requires spaces around its separate arguments (and around its name, [), and its last argument must be ]. There are grounds to argue that = rather than == is more portable (but == works OK in Bash).

Upvotes: 2

Related Questions