1

I'd like to let the user override some variables I use in an existing script, and I wondered if there were an easy way to do this in a generic way. For example my script is:

LOG_LEVEL="DEBUG"
echo $LOG_LEVEL

Now if I run

./myscript.sh LOG_LEVEL="INFO"

I'd like the LOG_LEVEL variable to be overriden by the parameter value. The underlying question is : is it possible to set a variable value from the variable name. The mechanism I'm asking for would require something like this:

set(varname, value)
1
  • You can try to set LOG_LEVEL using the value of a positional parameter ($1 f.e.) and DEBUG as its default value: LOG_LEVEL=${1:-DEBUG}. Commented Nov 5, 2018 at 11:13

3 Answers 3

3

Well, you could do it the native way.

LOG_LEVEL="INFO" ./myscript.sh 

Would that be sufficient?

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

2 Comments

Inside the script, you can set a default like : ${LOG_LEVEL:=INFO} which will take effect if no value is passed in the environment.
It also needs a statement in the script to check if LOG_LEVEL is not set and use a default value to set it in this case.
1

You could look for arguments that look like variable assignments and eval them:

#!/bin/sh

for arg
do
  if printf '%s' "${arg}" |
      grep -q '^[A-Z_]\+='
  then
    IFS='=' read -r var val <<EOF
${arg}
EOF
    eval "${var}=$(printf '%s' "${val}" |
                     sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/'/")"
  fi
done

printf 'LOG_LEVEL=%s\n' "${LOG_LEVEL:-}"

The grep -q '^[A-Z_]\+=' part is what determines what looks like an assignment. It could be tweaked to be more allowing, e.g. lower-case variable names, or more restrictive, e.g. ^LOG_LEVEL=.

The above tries to be clever about special characters in the value, but I can’t guarantee it won’t fail horribly in some strange cases.

2 Comments

Seems to do what I need bu Noufal Ibrahim's solutions is more simple.
@jaudo It sure is. And safer and more allowing too. 😉 I just found it a fun challenge.
0

There are several ways to set a variable via a variable name indirectly. printf -v is one of them. Try something like:

#!/bin/bash

LOG_LEVEL="DEBUG"
LOG_FILE="/tmp/log.txt"

for arg in "$@"; do
    if [[ "$arg" == *?=?* ]]; then
        varname="${arg%=*}"    # lvalue
        value="${arg#*=}"      # rvalue
        printf -v "$varname" %s "$value"
    fi
done

echo "LOG_LEVEL=$LOG_LEVEL"
echo "LOG_FILE=$LOG_FILE"

Then try to invoke: ./thisscript LOG_LEVEL="INFO" LOG_FILE="/dev/null" or whatever.
Hope this helps.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.