0

I saved ports in an array that I wanted to check, then I'm running a for loop to check for the port in iptables rule list. I want to echo Ports that are not in the iptables list with msg not found. Tried to add an if condition inside the loop but not working. here's the code: [Non-working ;) ]

#!/bin/bash
array=( 3306 1403 8080 443 22 )
for i in "${array[@]}"
pc=(iptables --list | grep $i | cut -d " " -f1)
do
if [ "${pc}" = "ACCEPT" ]
then 
echo "ok"
else
echo "Port not found"
fi
done

Error:

array.sh: line 4: syntax error near unexpected token `|'
array.sh: line 4: `pc=(iptables --list | grep $i | cut -d " " -f1)'
array.sh: line 5: syntax error near unexpected token `do'
array.sh: line 5: `do'
5
  • What doesn't work? Commented Sep 30, 2022 at 17:46
  • @BenjaminW. whole script. some syntax issues? Commented Sep 30, 2022 at 17:52
  • Indeed ... have you put it in ShellCheck ?:) Commented Sep 30, 2022 at 18:02
  • the pc=... line should certainly be after to "do" keyword. And you probably meant pc=$(...) not pc=(...) Commented Sep 30, 2022 at 18:08
  • "The whole script doesn't work" could mean many things. Do you get an error? Unexpected output? What output did you expect? Commented Sep 30, 2022 at 18:09

3 Answers 3

1

I am not attempting to syntax check the entire script, but there appears to me an obvious issue; you're assigning the pc evar before the do. This becomes very evident if you format your code with tabs. For example:

#!/bin/bash
array=( 3306 1403 8080 443 22 )

for i in "${array[@]}"
pc=(iptables --list | grep $i | cut -d " " -f1)
do
    if [ "${pc}" = "ACCEPT" ]
    then 
        echo "ok"
    else
        echo "Port not found"
    fi
done

From the above, you can see that pc is not being set inside the for loop. Try this instead:

#!/bin/bash
array=( 3306 1403 8080 443 22 )

for i in "${array[@]}"
do
    pc=$(iptables --list | grep $i | cut -d " " -f1)
    if [ "${pc}" = "ACCEPT" ]
    then 
        echo "ok"
    else
        echo "Port not found"
    fi
done

Edit: Also, @tink (made it 1 minute before me) noticed there's a missing $ in the assignment of the pc variable. I've updated my answer to make that clear as well. HTH

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

1 Comment

Plus pc=$(...) not pc=(...)
0

Two syntax issues:

#!/bin/bash
array=( 3306 1403 8080 443 22 )
for i in "${array[@]}"
do
    pc=$(iptables --list | grep $i | cut -d " " -f1)
    if [ "${pc}" = "ACCEPT" ]
    then 
        echo "ok"
    else
        echo "Port not found"
    fi
done

Comments

0

An alternative using a while + read loop and ProcSub. Instead of embedding grep and cut inside the for loop.

#!/usr/bin/env bash

array=( 3306 1403 8080 443 22 )

regex=$(IFS='|'; printf '%s' "${array[*]}")

while read -r pc port; do
  if [[ "$pc" = "ACCEPT" ]]; then
    printf '%s is Ok.\n' "$port"
  else
    printf >&2 'Port %s not found.\n' "$port"
  fi
done < <(iptables --list | grep -E "$regex")

Tested against a file that contains the following.

ACCEPT 3306
REJECT 1403
REJECT 8080
ACCEPT 443
ACCEPT 22

Change:

iptables --list | grep -E "$regex"

To

cat file.txt | grep -E "$regex"

Just to simulate the iptables command.


Output

3306 is Ok.
Port 1403 not found.
Port 8080 not found.
443 is Ok.
22 is Ok.

That is a minimal assumption from the output of iptables --list, adjust the pattern matching if needed but that is the idea.

Comments

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.