3

Ok so instead of hardcoding some local env variables that mirror a remote server (OpenShift server), I'd like to programmatically do it, so we don't have to keep everything up-to-date manually.

Right now I have this hardcoded in a file:

#!/usr/bin/env bash

export OPENSHIFT_MONGODB_DB_USERNAME="admin"
export OPENSHIFT_MONGODB_DB_PASSWORD="xyz"
export OPENSHIFT_MONGODB_DB_HOST="emsa-xyz-2-emsa.cloudapps.nabisco.com"
export OPENSHIFT_MONGODB_DB_PORT=60161

Instead of hardcoding, I can retrieve the "public" env variables from OpenShift with this command:

rhc env list -a <app-name>

which writes this to stdout:

NODE_ENV=jailbreak
NPM_CONFIG_PRODUCTION=true
OPENSHIFT_MONGODB_DB_HOST=emsa-xyz-2-emsa.cloudapps.nabisco.com
OPENSHIFT_MONGODB_DB_PASSWORD=xyz
OPENSHIFT_MONGODB_DB_PORT=60161
OPENSHIFT_MONGODB_DB_USERNAME=admin

does anyone know how I can take that stdout, and, in turn, export each of those variables?

I assume it would be like so - get each line and then put export in front of it and then run bash -e "export x"...the problem is that probably runs in a subshell and wouldn't effect the current shell?

The existing answer to this question is good and should not be lost.

2
  • Right but the answer given to this question is probably better than the answers given to the other question, at least it's more thorough in explanation. Nov 23, 2017 at 1:23
  • If this is a dupe question, it's a super dupe question if you ask me! Mar 22, 2018 at 17:08

1 Answer 1

2

If you have trust in the output of your rhc command, you can just source it:

. <(rhc env list -a <app-name>)

This will source (execute) each line that rhc produces.

As written, the code above defines the variables but doesn't export them. We could fix that but the code below is safer and does the exporting.

The source command, ., expects a file as an argument. To convert the output of rhc into a file-like object, we use process substitution: <(...).

To be more secure, use:

while read -r line; do declare -x "$line"; done < <(rhc env list -a <app-name>)

Here, we use process substitution, <(...), combined with input redirection, <, so that the while loop reads from the output of rhc. The space between the first and second < is essential: do not omit it.

The -x option to declare tells bash to export the variable.

Changing order

As per comment below, the rhc command can be placed on the line above the while loop via:

tmpvar=$(rhc env list -a <app-name>)
while read -r line; do declare -x "$line"; done <<<"$tmpvar"

<<< creates a here string. In this case, it means the $tmpvar is provided as input to the while loop.

12
  • Nice very cool, there is no manual entry for declare - man declare doesn't seem to exist at least on my MacOS machine, wonder how it works so that it acts as export Nov 23, 2017 at 1:17
  • 1
    @AlexanderMills declare is a bash builtin. To get help on it, run help declare or else open up man bash and look at the section entitled SHELL BUILTIN COMMANDS.
    – John1024
    Nov 23, 2017 at 1:21
  • Do you know of a way to put the rhc command on the line above the while loop? Nov 23, 2017 at 1:47
  • For now, I am guessing just store it in a variable and it should work. Nov 23, 2017 at 1:48
  • 1
    @AlexanderMills < <(...) takes the output of the command inside the parens and provides it as input to the while loop. By contrast, <<< takes the contents of the string that follows (in this case, the contents of $tmpvar) and provides it as input to the while loop. <<< is called a here string and is documented in man bash.
    – John1024
    Nov 23, 2017 at 1:59

Not the answer you're looking for? Browse other questions tagged .