1

In a script i have a function which evaluates passed 'key=value' parameters, i.e.:

function evaluateKeyValuePair() {
    eval "$1"
}

evaluateKeyValuePair "key=value with whitespaces"
evaluateKeyValuePair "key=value"

The latter call works fine, "echo $key" prints "value". However calling the function with whitespaces in "value" does not work: a command-not-found error is thrown for "with" and "whitepaces"

I've already read that using eval generally is a bad idea. But, unfortunately i cannot change the basic layout of the function(s). I just have to live with it.

I tried to change it to:

function evaluateKeyValuePair() {

    key="${1%%=*}"
    val2="${1#*"="}"

    eval $key="$val2"
}

but this does not work either.

Is there a way to evalute key-pair-values with whitespaces in "value" or do i have to test for whitespaces in the passed parameter and return an error if there are any?

THX in advance!

PuppetMaster
  • 21
  • 1
  • 7
  • This is a bad idea; `bash` already has a way of passing values this way: `key="value with whitespace" ./script` will make `key` available inside `script`. It's not clear what your actual use case is, but this is almost certainly the wrong solution. – chepner Nov 22 '15 at 15:52
  • If you're reading all these lines from a file, is there anything else in that file? Could you just `source` the file instead of trying to process it yourself? – Eric Renouf Nov 22 '15 at 15:54
  • @chepner: Your suggestion would not work, since some key-value-pairs might be available only after the script has been started or change during runtime. – PuppetMaster Nov 22 '15 at 16:06
  • @Eric Renouf: Unforunately, there are lines with other key-value-pairs and certain variables must not be overwritten. Indeed, there is a test in the function which checks, if a read-in variable is allowed to be overwritten or not. I just dropped that part here. – PuppetMaster Nov 22 '15 at 16:10

3 Answers3

2

In bash, you can perform the assignment using the declare built-in, instead of eval. This avoids having to insert escaped quotes into the argument.

Note that in a function, declare is equivalent to local so that it is necessary to add the -g (global) flag (implemented in v4.2; prior that that, you would have to use export to avoid making the variable local):

evaluateKeyValuePair() {
  declare -g "$1"
}

Example:

$ evaluateKeyValuePair "key=value with whitespaces"
$ echo "$key"
value with whitespaces
rici
  • 234,347
  • 28
  • 237
  • 341
0

Try using single quote

function evaluateKeyValuePair() {
    eval "$1"
}

evaluateKeyValuePair 'key="value with whitespaces"'
evaluateKeyValuePair "key=value"

You can also escape the double quotes like this :

evaluateKeyValuePair "key=\"value with whitespaces\""
Luc M
  • 16,630
  • 26
  • 74
  • 89
  • Hello Luc! Thanks for your answer. This would not work, since usually the key-vlaue-pairs are read from files. So i would have to transforms the lines into suitable formats and i hoped that would not be necessary. Sometimes the evaluation is needed for user input validation. But you lead me into the right direction: eval $key='$val2' works both for "key=value with whitepaces" and key="value with whitespaces". Thanks a lot for your support! – PuppetMaster Nov 22 '15 at 15:48
0

With your second attempt and the answer here you can do what you want without the eval:

function evaluateKeyValuePair() {
    key="${1%%=*}"
    val2="${1#*"="}"

    printf -v $key "$val2"
}

evaluateKeyValuePair "key=value with whitespaces"
printf "%s\n" "$key"

which will print value with whitespaces

Community
  • 1
  • 1
Eric Renouf
  • 13,950
  • 3
  • 45
  • 67