I am struggling to figure out a way to reduce code duplication. Specifically when checking if a variable is set. My code currently looks like this:

# webadmin enabled
if [ -f "${servercfgfullpath}" ]; then
    webadminenabled=$(grep "ControlPanelEnabled" "${servercfgfullpath}" | sed 's/^.*value="//' | cut -f1 -d"\"")
    if [ ! -n "${webadminenabled}" ]; then
        webadminenabled="NOT SET"

# webadmin port
if [ -f "${servercfgfullpath}" ]; then
    webadminport=$(grep "ControlPanelPort" "${servercfgfullpath}" | tr -cd '[:digit:]')
if [ ! -n "${webadminport}" ]; then

In summery the code first checks that a config file is available if not displays "UNAVAILABLE" to the user. If config file is available will attempt to get specific info from the config file to the user, should that fail it will display "NOT SET" instead.

Not really an issue if only used a few times however this is duplicated many times and although works it is far from ideal as it gets very hard to read.

serverconfigpath variable I believe is easy enough to improve however I would like to create a function or a way to simply set a variable to "NOT SET" if the variable was unable to get the information it needed.

Any ideas or pointers on how to streamline this code?

Here is the specific file with the offending code https://github.com/dgibbs64/linuxgsm/blob/master/functions/info_config.sh


The variable assignments could be simplified as follows:

if [ ! -n "${varname}" ]; then
    varname="some default"

is equivalent to

varname=${varname:-"some default"}

and, even more terse,

: ${varname:="some default"}

To parametrize this for arbitrary variable names and default values, I suggest to define a function. bash insists on an explicit variable name for parameter substitution with ${...}, so specifying an indirect variable or command instead of varname doesn't seem possible (to me):


# exec_with_default
# Assign command output to specified variable, or assign default value if
# output empty
# $1 : command
# $2 : variable to be set
# $3 : default value for variable

function exec_with_default {
    local t="$($1)"    # Assign command output to temporary variable t
    : ${t:="$3"}       # Perform bash parameter subsitution on t
    eval "$2=\$t"      # Indirectly assign t to variable name provided in $3

exec_with_default "echo something" "varname" "not set"
echo $varname

exec_with_default "echo" "varname" "not set"
echo $varname
  • nice! tested and looks good. Is there a way to do something like varname=${$(command):-"some default"} ? since it could make the code as simple as bolting NOT SET to the end of the variable.
    – dgibbs
    Apr 24 '16 at 21:37
  • 1
    @dgibbs Not to my knowledge, since the ${left:-right} expects left to be a variable name. See my updated answer for a suggested workaround with a function.
    – Guido
    Apr 24 '16 at 23:09
  • Thanks this has been very helpful I am going to try all this out :D
    – dgibbs
    Apr 26 '16 at 20:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.