2

I have a script for which I need to pass a string which contains variables and text to conform an URI.

An example of this would be:

URI="${PROTO}://${USER}:${PASS}@${HOST}/${TARGET}"

The variables ${PROTO}, ${USER}, ${PASS}, ${HOST} and ${TARGET} are not defined when I define the variable $URI but they will be when the Bash Script is going to be executed so I need to expand URI to the final form of the string.

How can I do that? I've read eval: When You Need Another Chance but I really don't like the idea of using eval as it might be dangerous plus it means to escape a lot of parts of the URI string.

Is there another way to do it? What's the recommended solution to this problem?

Thanks M

2 Answers 2

3

A variable stores data; if you don't have values for PROTO et al. yet, then you don't have data. You need a template.

uri_template="%s://%s:%s@%s/%s"

Later, when you do have the rest of the data, you can plug them into the template.

uri=$(printf "$uri_template" "$PROTO" "$USER" "$PASS" "$HOST" "$TARGET")

(In bash, you can avoid the fork from the command substitution by using the -v option: printf -v uri "$uri_template" "$PROTO" "$USER" "$PASS" "$HOST" "$TARGET".)

You can also define a function:

uri () {
    # I'm being lazy and assuming uri will be called with the correct 5 arguments
    printf "%s://%s:%s@%s/%s" "$@"
}

# Variables and functions exist in separate namespaces, so the following works
uri=$(uri "$PROMPT" "$USER" "$PASS" "$HOST" "$TARGET")
Sign up to request clarification or add additional context in comments.

1 Comment

I can work from your answer to a proper solution but just in case I'd like to explain my problem a little bit further to see if you can come up with a solution different to what I'm thinking. The URI can come with variables or with the values already. So it's not like I could do the solution you propose straightforward. I think I can match with a regesxp if and which variables are present and then do what you say depending on the result.
3

Before executing the script, define the variables using 'export'.

export PROTO='http'
export USER='bob'
export PASS='password'
export HOST='myhostname'
export TARGET='index.html'

bash ./myscript_with_uri.sh

OR

Create the URI script as a procedure that will return the URI.

uri_creater.sh

makeUri ()
{
    URI="${PROTO}://${USER}:${PASS}@${HOST}/${TARGET}
}

script_using_uri.sh

. uri_creater.sh
PROTO='http'
USER='bob'
PASS='password'
HOST='myhostname'
TARGET='index.html'

makeUri

url="${URI}"

echo "${url}"

Tested on Centos 6.5 with bash.

1 Comment

1) The 'export' command makes the variables available to sub shells. 2) The '.' causes the script to be imported 3) Variables are evaluated when used. As long as they are set before evaluated, it will work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.