Hi I'am recently started learning bash scripts, since I'm quite "green" so to speak I hope I can get some help. I have this problem that I just can't seem to figure out on my own. I want this program to read through every line to check if there are any iptables rules for a given IP address. If there is: Take the number of the line, and then change or delete it with the iptables -R INPUT $lineNumberHere -s $IP_ADDRESS -j $newPolicy.
However the program starts reading the first lines and registers the line number as a "Chain" and "num" which causes the error. Is there a method of bypassing these two lines?
Just to clarify. I am running the program as root
# The IP address is listen in rules
# Find the line number of the rule
echo ""
echo "The IP allready has a rule in iptables"
iptables -L INPUT --line-numbers | while read line; do
echo ""
echo "Checking line: $line"
LINE_NUMBER=$(($line | cut -d " " -f1))
BANNED_IP=$(($line | cut -d " " -f4 | cut -d "/" -f1))
re='^[0-9]+$'
if [[ "$LINE_NUMBER" =~ $re ]]; then
echo "Line nr. $LINE_NUMBER"
if [ "$IP_ADDRESS"="$BANNED_IP" ]; then
echo "Changing status to BANNED"
iptables -R INPUT "$LINE_NUMBER" -s "$IP_ADDRESS" -j DROP
fi
else
echo "error: Not a number" >&2
continue;
fi
done
There are several syntax problems in this script. In the lines:
LINE_NUMBER=$(($line | cut -d " " -f1))
BANNED_IP=$(($line | cut -d " " -f4 | cut -d "/" -f1))
...there are two problems: $(( ))
evaluates its contents as an arithmetic expression, not as a command (that's why you're getting a "syntax error in expression" error). To run a command and capture its output, you want a single level of parentheses: $( )
instead of $(( ))
.
The other problem is with the command pipeline inside that rhe elements of a pipeline must be commands, and $line
isn't one, it's just data. You want something like $(echo "$line" | cut ...)
.
The other problem I see immediately is in this line:
if [ "$IP_ADDRESS"="$BANNED_IP" ]; then
you need spaces around the =
operator; without them, it's not recognized as an operator at all, just part of a single long string. So use this instead:
if [ "$IP_ADDRESS" = "$BANNED_IP" ]; then
There may be other problems, these are just the ones that I spotted on inspection. BTW, I recommend shellcheck.net as an easy tool to point out common mistakes in bash scripts.