0

Given a file of the following format:

whitelist_a=["10.2.3.4", "10.6.7.8"]
whitelist_b=["192.2.3.4", "192.6.7.8"]

How can I parse it and use eval to create local variables for each key-value pair that I can reference later in my script? This is what I've tried so far:

WHITELISTS=./whitelists.txt

IFS="="
while read -r name value
do
  eval "$name=${value}"
done < $WHITELISTS

If I temporarily change the eval to echo then from the output I can see the lines being parsed as expected:

whitelist_a=["10.2.3.4", "10.6.7.8"]
whitelist_b=["192.2.3.4", "192.6.7.8"]

However, switching back to eval I get 10.6.7.8]: command not found, which I'm presuming is because the double quotes haven't been escaped. What do I need to change to make this work?

John Topley
  • 113,588
  • 46
  • 195
  • 237
  • 1
    You don't need to `eval` the string rather use the `declare` built-in to initialize the variables. Also you don't need to set `IFS` globally throughout your script, but make it local to the `read` command as `while IFS== read -r key value; do declare "$key"="$value"; done < whitelists.txt` – Inian Apr 16 '19 at 10:25
  • @AlexHarvey: I'm waiting for OP's clarification, if the dupe is valid, from the looks the question seems to parse the config value and set variables in the shell. It's been answered int the other question – Inian Apr 16 '19 at 10:36
  • @AlexHarvey: The RHS value doesn't matter as long as it's parsed out as in my first comment. It sets those variables as OP wants – Inian Apr 16 '19 at 10:37
  • @AlexHarvey: If people think its not a dupe as you claim it to be, they can re-open the post with enough reopen posts – Inian Apr 16 '19 at 10:39
  • @AlexHarvey: I don't think its ugly in any way as you claim it to be. It sets the shell variable to the value on the RHS which is what OP wants. Feel free to add a better logic if you have – Inian Apr 16 '19 at 10:40
  • @AlexHarvey: It is not mentioned anywhere, OP wants the RHS to be parsed as a JSON. I can see only terms to be used as a shell variable. If OP feels otherwise I would gladly re-open, but as of now it remains a dupe – Inian Apr 16 '19 at 10:41
  • @AlexHarvey In the interests of brevity I probably over-simplified the question. My actual use-case is that I'm ultimately trying to pass the array of IP addresses as an argument to `terraform apply` i.e. `terraform apply -var "whitelist_a=[\"10.2.3.4\", \"10.6.7.8\"]"` etc. – John Topley Apr 16 '19 at 11:15
  • 1
    Oh. Can you just edit the source file instead? `gsed -i 's/=\(.*\)/='\''\1'\''/' whitelists.txt ; source whitelists.txt`. That just turns the source file into valid Bash code. Or the other way suggested above. – Alex Harvey Apr 16 '19 at 11:20
  • Seems like you could also just pass the file as-is to `terraform apply -var-file=whitelists.txt`. https://learn.hashicorp.com/terraform/getting-started/variables.html – Alex Harvey Apr 16 '19 at 11:33

0 Answers0