2

I need to generate ipset rules dynamically. so i created following script and having error try to get the urls from array.

#!/bin/bash

# urlList
allow_SMTP_OUT_URLS=(mtp.sendgrid.net)
allow_HTTP_OUT_URLS=(archive.mariadb.org)
allow_HTTPS_OUT_URLS=(ppa.launchpad.net repo.mongodb.org www.google.com)
allow_SSH_OUT_URLS=(bitbucket.org)

ipsetNames=(allow_HTTP_OUT allow_HTTPS_OUT allow_SMTP_OUT allow_SSH_OUT)

for ipSET in "${ipsetNames[@]}"
do

   ipset create -exist $ipSET hash:ip timeout 86400 comment family inet

   chkIPSETexsit="$(ipset list -n | grep $ipSET)"

# Check / Adding IPSET rules
   if [ -z "$chkIPSETexsit" ]; then
       echo "$ipSET is empty"
       exit 1
   else
       echo "$ipSET is present. Adding URLs to ipset"

       urlList=$ipSET
       urlList+="_URLS"

       echo "urlList: $urlList"

       echo URLs:   ${(echo $urlList)[@]}
   fi
done

its gives error as bad substitution

allow_HTTP_OUT is present. Adding URLs to ipset
urlList: allow_HTTP_OUT_URLS
/root/salt-cron-scripts/test2.sh: line 30: ${(echo $urlList)[@]}: bad substitution

Any suggestions to correct this please

1
  • You've reached the level of data manipulation where bash is no longer appropriate to use. Choose a language with proper data structures. Commented Nov 28, 2017 at 0:28

2 Answers 2

2

You can use a nameref declared with declare -n. This gives you a slightly better and more intuitive manipulation than using indirect parameter expansion, such as using: ${urls[@]}, ${urls[0]}, ${urls[5]//a/b} etc.

#!/bin/bash

# urlList
allow_SMTP_OUT_URLS=(mtp.sendgrid.net)
allow_HTTP_OUT_URLS=(archive.mariadb.org)
allow_HTTPS_OUT_URLS=(ppa.launchpad.net repo.mongodb.org www.google.com)
allow_SSH_OUT_URLS=(bitbucket.org)

ipsetNames=(allow_HTTP_OUT allow_HTTPS_OUT allow_SMTP_OUT allow_SSH_OUT)

for ipSET in "${ipsetNames[@]}"
do

   ipset create -exist $ipSET hash:ip timeout 86400 comment family inet

   chkIPSETexsit="$(ipset list -n | grep $ipSET)"

# Check / Adding IPSET rules
   if [ -z "$chkIPSETexsit" ]; then
       echo "$ipSET is empty"
       exit 1
   else
       echo "$ipSET is present. Adding URLs to ipset"

       urlList=${ipSET}_URLS
       echo "urlList: $urlList"
       declare -n urls=$urlList
       echo "URLs: ${urls[@]}"

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

1 Comment

Thank you very much for the explanation it's really helpful.
2

You need to use indirect parameter expansion to expand the array named by urlList.

allow_SMTP_OUT_URLS=(mtp.sendgrid.net)
allow_HTTP_OUT_URLS=(archive.mariadb.org)
allow_HTTPS_OUT_URLS=(ppa.launchpad.net repo.mongodb.org www.google.com)
allow_SSH_OUT_URLS=(bitbucket.org)

ipsetNames=(allow_HTTP_OUT allow_HTTPS_OUT allow_SMTP_OUT allow_SSH_OUT)

for ipSET in "${ipsetNames[@]}"
do

   ipset create -exist "$ipSET" hash:ip timeout 86400 comment family inet

   chkIPSETexsit="$(ipset list -n | grep $ipSET)"

   # Check / Adding IPSET rules
   if [ -z "$chkIPSETexsit" ]; then
       echo "$ipSET is empty"
       exit 1
   fi

   echo "$ipSET is present. Adding URLs to ipset"

   urlList=${ipSET}_URLS
   echo "urlList: $urlList"
   urlList=$urlList[@]

   echo "URLs: ${!urlList}"
done

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.