24

Kind of a tricky one to name this...

Basically I have a program which when run prints on STDOUT a set of shell variables:

$ ./settings
SETTING_ONE="this is setting one"
SETTING_TWO="This is the second setting"
ANOTHER_SETTING="This is another setting".

I want to run this from within a shell script as if the STDOUT were being evaluated with source.

I'd like to do something like ...

source `./settings`

... but of course that doesn't work.

I know I could do:

./settings >/tmp/file
source /tmp/file

but I really don't want to do that.

Any clues?

Majenko
  • 32,964

5 Answers5

29

On systems where /dev/fd is available, bash supports process substitution:

source <(./settings)

Here, <( ) will expand to an automatically assigned path under /dev/fd/... from which the output of ./settings can be read.

grawity
  • 501,077
26

You can use eval:

eval "$(./settings)"

eval "`./settings`"
Keith
  • 8,293
7
declare `./settings`

Or of course...

export `./settings`

Test it of course...

export `echo -e "asdf=test\nqwerty=dvorak"` ; echo $asdf $qwerty

Handling whitespace:

eval export `./settings`
grawity
  • 501,077
Hello71
  • 8,673
  • 5
  • 42
  • 45
6

source /dev/stdin < ./settings

I think /dev/stdin is a Linux only thing though.

LawrenceC
  • 75,182
1

Wanted to provide another perspective here, as the other answers create files and don't directly pull from stdin. I have some builds that need to send some prepared environment information to multiple scripts. What I'm doing is preparing a bunch of Bash compatible variable assignments in a string:

Var1="Foo"
Var2="Bar"
Var3="Baz"

When I'm preparing to execute the script, I base64 encode the above multiline string and pipe it into my shell script:

echo base64EncodedParameters | build.sh

In build.sh I read from stdin, base64 decode and eval the result.

params=""
while read line; do params="${params}${line}"; done
eval `echo $params | base64 -D`

echo "Hello ${Var1} ${Var2}"