Store runtime configuration within shell script using simple but an effective method.
Shell script
I will use the following shell script to illustrate the idea. Nothing fancy, it will display available disk space on specific server and partition.
#!/usr/bin/env bash # Display available disk space on specific server and partition # default parameters default_bastion="" default_busername="" default_server="localhost" default_username="milosz" default_partition="/srv" # nextcloud server nextcloud_server="nextcloud.local" nextcloud_partition="/data" # dokuwiki server dokuwiki_bastion="bastion.example.org" dokuwiki_busername="bouncer" dokuwiki_server="192.0.2.10" dokuwiki_username="dokuwiki" dokuwiki_partition="/wiki" # kolab server kolab_bastion="bastion.example.org" kolab_busername="bouncer" kolab_server="192.0.2.20" kolab_username="monitoring" kolab_partition="/" # get defined servers/applications applications="$((set -o posix; set) | awk -F '=' '/_server/ {split($1,array,"_"); print array[1]}' | grep -v default)" # get defined attributes attributes="$((set -o posix; set) | awk -F '=' '/default_/ {split($1,array,"_"); print array[2]}')" for application in $applications; do # define attributes for server/application for attribute in $attributes; do application_attribute="${application}_${attribute}" default_attribute="default_${attribute}" if [ -n "${!application_attribute}" ]; then eval "${attribute}"="${!application_attribute}" else eval "${attribute}"="${!default_attribute}" fi done # perform an action if [ -n "$bastion" ]; then bastion_param="-J ${busername}@${bastion}" else bastion_param="" fi echo -n "$server: " ssh $bastion_param $server -l $username "bash -c 'df -h --output=avail $partition | sed 1d'" done
Usage
Execute the above-mentioned shell script to see available disk space on specified servers.
nextcloud.local: 87G 192.0.2.10: 98G 192.0.2.20: 5,5G
How it works
Attributes
Define default values, remember to include the empty ones.
# default parameters default_bastion="" default_busername="" default_server="localhost" default_username="milosz" default_partition="/srv"
These variables will be used to extract attribute names.
# get defined attributes attributes="$((set -o posix; set) | awk -F '=' '/default_/ {split($1,array,"_"); print array[2]}')"
Extracted attribute names.
attributes="bastion busername server username partition"
Applications
Define attributes for each application.
# nextcloud server nextcloud_server="nextcloud.local" nextcloud_partition="/data" [...]
These variables will be used to extract application names.
server
attribute as an application indicator in this example.# get defined servers/applications applications="$((set -o posix; set) | awk -F '=' '/_server/ {split($1,array,"_"); print array[1]}' | grep -v default)"
Extracted applications names.
applications="nextcloud dokuwiki kolab"
Parsing attributes for each application
I will iterate over the list of applications.
for application in $applications; do
Assign attributes (like server
, username
, …) using application_attribute
variable (values like nextcloud_server
, nextcloud_username
, … depending on the application name) to define target variable name and read value using ${!application_attribute}
construct. Use default value if it is empty.
# define attributes for server/application for attribute in $attributes; do application_attribute="${application}_${attribute}" default_attribute="default_${attribute}" if [ -n "${!application_attribute}" ]; then eval "${attribute}"="${!application_attribute}" else eval "${attribute}"="${!default_attribute}" fi done
Perform desired actions using short attribute names.
# perform an action if [ -n "$bastion" ]; then bastion_param="-J ${busername}@${bastion}" else bastion_param="" fi echo -n "$server: " ssh $bastion_param $server -l $username "bash -c 'df -h --output=avail $partition | sed 1d'"
End of the application loop is self-explanatory.
done
Additional notes
source
configuration and additional functions to keep these parts separate from main shell script.