Originally published February 27, 2021 @ 11:03 am

A few quick tips on using variables in your Bash scripts. Nothing fancy here, just good practices that we often overlook.

Simple stuff

var1=23
var2="twenty three"
echo "${var1},${var2}"

Assigning variables from user input

read -p "Enter username: " u
read -s -p "Enter password: " p

Reading variables that contain a backslash

read -r i <<<"$(echo "a\bc")"

Assigning multiple variables from command output

IFS='^' read var1 var2 var3 <<<"$(echo "value1^value2 with a space^value3")"

Assigning multiple variables from another variable

k="value1 value2 value3"
IFS=' ' read var1 var2 var3 <<<"${k}"

Assigning multiple variables from pipe

# Variables will be unset when subshell exists
echo 1 2 3 | { read a b c; echo $b; }

 

Checking Variables

If the variable not set, say something

if [ -z "${var}" ]; then echo "Uh-oh"; fi

Check if the variable is set and is not a space

i=" "
if [[ -z "${i// }" ]]; then echo "i is not set"; else echo "i is $i"; fi

If one or more variables not set, say something

" /root/movies
if [[ -z "${var1}" || -z "${var2}" || -z "${var3}" ]]; then echo "Uh-oh"; fi

If one or more variables not set, say something and do something

([ -z "${var1}" ] || [ -z "${var2}" ] || [ -z "${var3}" ]) && (echo "Uh-oh" && exit 1)

If variable not set, set it to some default value

var=${var:="default value"}

If a variable is not an integer, set it to zero

[[ "${var}" =~ ^[0-9]+$ ]] || var=0

If multiple variables are not set, assign them a default value

for i in var{1..3}; do
if [ -z "$(eval echo $(echo $`eval echo "${i}"`))" ] ; then
eval "$(echo ${i})"="$(echo "default_value")"
fi; done

 

Working with arrays of variables

If you really have lots and lots of variables that require different default values, you may use a table. Parse this table to populate two arrays: one containing names of the variables and the other – their default values. Let’s say your table.txt looks like this:

variable_1,default_value
variable_two,some other default value
variable_whatever,nothing to see here

We will use it to build two arrays:

IFS=$'\n'
array_variables=($(awk -F, '{print $1}' table.txt))
array_defaults=($(awk -F, '{print $2}' table.txt))
unset IFS

Now we can read the array_variables array, check if the variables are set and, if not, assign a corresponding default value from the array_defaults array:

for ((i = 0; i < ${#array_variables[@]}; i++))
do
if [ -z "$(eval echo $(echo $`eval echo "${array_variables[$i]}"`))" ]
then
eval "$(echo "${array_variables[$i]}")"="$(echo "\"${array_defaults[$i]}\"")"
fi
done

And to check that the variables have been set:

for i in $(printf '$%s\n' ${array_variables[@]}); do eval echo ${i}; done

default_value
some other default value
nothing to see here