0

I'm new in here and with bash scripting.

I have few exercises but I'm already stuck in the first one.

So I'll explain: With a script, I have to check an IP address, written by hand e.g 51.32.12.51 and then, with two files created by me (accept.txt and deny.txt) check if that address is accepted or denied. So far, I have done this, but I'm totally stuck here.

#!/bin/bash

IPS_acc="`cat accept.txt`"
IPS_den="`cat deny.txt`"

read -p "Quina IP vols comprovar? " IP


for ipfitxer in $IPS_acc $IPS_den
do

  if [ "$IP" = "$ipfitxer" ]; then

  echo "La $IP està acceptada explícitament"

  elif [ "$IP" != "$ipfitxer" ]; then

  echo "La IP $IP està denegada explícitament"
  fi
done

If anything is not understood, I can translate it.

Thanks in advance.

1
  • Welcome Kevin, it looks like you're trying to see if an IP address is in one or the other of the files you've created so you're trying to find a "string" the IP in a "file". A search for existing questions about how to find a string in a file will help you find what you need. Commented Feb 28, 2020 at 1:42

1 Answer 1

2

Here is one way using grep(1) and an if-statement

#!/usr/bin/env bash

ips_acc=accept.txt
ips_den=deny.txt

read -p "Quina IP vols comprovar? " IP

if grep -wq "$IP" "$ips_acc"; then
  echo "input $IP is accepted"
elif grep -wq "$IP" "$ips_den"; then
  echo "input $IP is denied"
else
  echo "$P is not known!" >&2
fi

This might be close to the code that you're trying to write, I just translated the words that you have in your code via google.

#!/usr/bin/env bash

ips_acc=accept.txt
ips_den=deny.txt

read -rp "Quina IP vols comprovar? " IP

if grep -wq "$IP" "$ips_acc" "$ips_den"; then
  echo "La $IP està acceptada explícitament"
  exit 0
else
  echo "La IP $IP està denegada explícitament"  >&2
  exit 1
fi
  • It is enclosed inside an if-statement so the action will depend on the exit status of grep.

  • -w force PATTERN to match only whole words.

  • -q suppress all normal output or silent.


Per OP's original code using a for loop but requires bash4+ feature, because of mapfile

#!/usr/bin/env bash

ips_acc=accept.txt  ##: Save the text files in variables
ips_den=deny.txt

mapfile -t accept < "$ips_acc"  ##: save the value text files in an array.
mapfile -t deny < "$ips_den"    ##: Using mapfile aka readarray.

main() {   ##: Create a function named main
  read -rp "Quina IP vols comprovar? " IP           ##: ask and save user input
  for ipfitxer in "${accept[@]}" "${deny[@]}"; do   ##: loop through both accept and deny values.
    if [[ $ipfitxer == "$IP" ]]; then               ##: if input and values match 
      echo "La $IP està acceptada explícitament"    ##: Print/send message that they did match 
      exit 0                                        ##: Exit the script with a zero (true) status
    fi
  done
  echo "La IP $IP està denegada explícitament"  >&2 ##: Send message to stderr if there was no match. 
  exit 1
}

main    ##: run/execute main function.

This one needs exglob.

#!/usr/bin/env bash

shopt -s extglob    ##: Enable shell globbing extglob.
ips_acc=accept.txt  ##: save the value text files in an array.
ips_den=deny.txt

mapfile -t accept < "$ips_acc"    ##: save the value text files in an array.
mapfile -t deny < "$ips_den"      ##: Using mapfile aka readarray.


both=("${accept[@]}" "${deny[@]}");  ##: merge both arrays.

pattern=$(IFS='|'; printf '%s' "@(${both[*]})")   ##: Format/prepare the arrays.

read -rp "Quina IP vols comprovar? " IP   ##: Read/store user input

if [[ ${IP:?You did not gave an answer!} == $pattern ]]; then  ##: Test if there was a match
  echo "La $IP està acceptada explícitament"  ##: Print/send message that they do.
  exit 0    ##: Exit gracefully with zero exit status
else
  echo "La IP $IP està denegada explícitament"  >&2  ##: If no match send message to stderr 
  exit 1   ##: Exit with 1 which is an error
fi
  • Disclamer, I don't speak your native language.

  • The ${IP:?You did not gave an answer!} is a form of P.E. parameter expansion.

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

7 Comments

This will match 1.2.3.255 when the IP of interest is 1.2.3.2.
Try -w option to avoid partial match.
The -F option means the pattern is not a regex, so for example -F "*.*" would literally search for *.* and you would not have to quote what would otherwise be the wildcard asterisk and the wildcard period.
also thank you @jarmod for pointing what might be a mistake on my side.
First of all thank you all, appreciate it. I have a question because my teacher explained me that there are two ways valid to do this, with if statement and for loop. If + grep said it was easier and for loop maybe would be a little bit more complicated. I decided to do it with for loop as I want to understand how really works, if now I struggle at least in future I won't struggle that much.. Is there any way to do it with for loop + if statement? Thanks.
|

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.