0

This question already has an answer here:

A bash script I have limited or no ability to modify is using an environment variable like:

"${SERVER_ADDRESS}"

The actual SERVER_ADDRESS value can only be determined dynamically at runtime so I would like to set SERVER_ADDRESS to a curl command that looks up the IP. Something like:

SERVER_ADDRESS='curl -s http://lookup.api.com'

What makes this more complicated is that the actual lookup will only return a part of the necessary address, so what I really need is some kind of concatenation:

SERVER_ADDRESS='$(curl -s http://lookup.api.com).restofaddress.com'

This will mean that the curl command will be run and evaluated when the string is assigned to the environment variable, however, I need that evaluation to take place in the script when it's run.

I have tried every possible way of formatting the text in that environment variable so that the script with just "${SERVER_ADDRESS}" will end up with the correct value, but I'm stumped. Perhaps it's simply not possible without adding a little more sophistication to the receiving script.

marked as duplicate by jayhendren, GAD3R, sam, HalosGhost, Jeff Schaller Dec 12 '16 at 20:34

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

0

Use double quotes instead of single quotes:

SERVER_ADDRESS="$(curl -s http://lookup.api.com).restofaddress.com"

Interpolations and expansions (e.g., variable expansion, or command expansion as is the case here) are performed inside of double-quoted strings, but not single-quoted strings.

  • Correct me if I'm wrong, but I believe that this will mean that the curl command will be run and evaluated when the string is assigned to the environment variable, however as I mentioned, I need that evaluation to take place in the script when it's run. – MWelch Dec 12 '16 at 19:16
  • Sorry, that wasn't clear to me. – jayhendren Dec 12 '16 at 19:18
  • 1
    There's no good way to make a lazily-evaluated environment variable. Can you instead change how your script is invoked? For instance, instead of calling it like /bin/bash /path/to/script.sh, can you call it like ` SERVER_ADDRESS="$(curl -s lookup.api.com).restofaddress.com" /bin/bash /path/to/script.sh`? – jayhendren Dec 12 '16 at 19:21
  • I think youre response about their being "no good way" is the best I'm going to get. I thought as much but given that I'm such a novice with bash scripting, I figured I'd check with the experts. Thank you! – MWelch Dec 12 '16 at 19:44
0

As jayhendren says, you should be using double quotes when you want to interpolate a variable. But where your variable name is immediately adjacent to valid variable name characters, you need to tell bash where the variable name begins and ends by enclosing the name in curly braces. It is rather hard to work out what you mean when you describe your problem in something which looks like code but does not execute to give the desired result, (or produces a very peculiar fqdn) but I think you should be doing something like....

ADDR="http://lookup.api.com/"
export ADDR
...
curl -s -o "${OUTPUTFILE}" "${ADDR}some/path"

Or do you mean that the url you actually want to retrieve is composed of a fragment returned by from http://lookup.api.com? If this is the case then you should go find a big stick and use it to repeatedly beat the person whom wrote the API while shouting "302! 302! 302!". If they are a lot bigger than you or have a gun, you might consider the method suggested by jayhedren, however although elegantly terse, this is not a particularly robust solution. Consider instead:

FRAG=`curl -s -o "${ADDR}some/path" | tr -d '\040\011\012\015'`
curl -s -o "${OUTPUTFILE}" "${ADDR}some/path"

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