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?

link|improve this question

50% accept rate
feedback

4 Answers

up vote 3 down vote accepted

You can use eval:

eval $(./settings)

eval `./settings`
link|improve this answer
Sorry, should have mentioned, it's /bin/sh not bash. $() doesn't work. I have updated the question. – Majenko Apr 18 '11 at 20:19
@Matt: Well, sh is bash on most systems. Unless of course you meant recent Ubuntu versions, where it has been replaced with dash. – Hello71 Apr 18 '11 at 20:24
@Matt: In that case, backticks should work. But you should add the exact version of sh too - it could be a symlink to dash, ash, busybox... I have not seen a copy of "the real 'sh'" live. – grawity Apr 18 '11 at 20:29
@Matt: So you've got an ... interesting system there. Especially since almost all "sh" variations support $( ) -- starting with Almquist's shell in 4.3BSD -- and it's POSIX too. (Note: not arguing, just curious.) – grawity Apr 18 '11 at 20:31
$() exists, it just doesn't work like that in this circumstance. FreeBSD 8.2's /bin/sh – Majenko Apr 18 '11 at 20:32
show 1 more comment
feedback

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.

link|improve this answer
In the bash manual, this is called "process substitution". – glenn jackman Apr 18 '11 at 20:46
feedback
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`
link|improve this answer
Aha, the export trick works! Thanks – Majenko Apr 18 '11 at 20:28
Now - how can I handle spaces in a value? – Majenko Apr 18 '11 at 20:30
@Matt: I can't use backticks in comments, so please see edited answer. – grawity Apr 18 '11 at 20:34
@grawity: Yes you can... a backtick --> ` <-- and here's another one --> ` <-- – Hello71 Apr 19 '11 at 2:24
feedback

source /dev/stdin < ./settings

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

link|improve this answer
that tries to source the content of settings. Even with './settings' it fails with './settings': Ambiguous (' = backtick) – Majenko Apr 18 '11 at 20:18
/dev/stdin works on BSD and Cygwin, too. – grawity Apr 18 '11 at 20:20
1  
Using |, however, is not going to work (at least not exactly), because both sides of the pipe are separate subprocesses, so sourced commands would not affect the current shell. – grawity Apr 18 '11 at 20:22
edited to reflect that. – ultrasawblade Apr 18 '11 at 20:46
feedback

Your Answer

 
or
required, but never shown

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