Using Variables in Bash
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