1

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.

5
  • No.. This is not working really.. Commented Apr 11, 2016 at 6:45
  • 1
    You need a space before the closing bracket like this:if [ "$A" == "$B" ]; then. Also it is better to use single equal for compatibility reasons. like if [ "$A" = "$B" ]; then. Commented Apr 11, 2016 at 6:54
  • 1
    Does anyone know of a good canonical duplicate for this? It is a quite common problem. Commented Apr 11, 2016 at 6:57
  • @JonathanLeffler We have tried to compile a list of common Bash questions in the bash tag wiki. It still needs improvement but the canonical dupe I think you are looking for is stackoverflow.com/questions/9581064/… Commented Apr 11, 2016 at 10:47
  • @tripleee: It seems the syntax error was only part of the trouble so I won't be closing his as a dupe. But thanks for the info about the list of common Bash questions. Commented Apr 11, 2016 at 12:40

3 Answers 3

3

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. :)

Sign up to request clarification or add additional context in comments.

Comments

2

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).

2 Comments

This is wrong.. because in all states it returns false
The syntax error is correctly identified and fixed. If you also have problems with the spacing in your string, that is a separate bag'o'worms which is hard for anyone not on your machine to resolve. So, you would get a syntax error from the test (aka [) command when you ran what you showed. The test might also fail after the syntax is fixed because of spacing problems.
1

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)

2 Comments

When It returns false it shows some junc data related to diff command. how can I discard them and just print false?
@MLSC use this: diff -q -Z <(echo "$A") <(iptables -L) && echo "True" || echo "False", here the -q option mean s quiet i.e -q, --brief report only when files differ

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.