Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to run a command that sources a script to take on some env. variables before executing, without sourcing them in my current shell.

test.env

export test=1

None of these commands echo the env. variable:

a) Shouldn't this work? Aren't I just executing these commands in a new shell and returning the output?

$ bash -c "source test.env && echo $test"

b) Here I execute test.env and try to run echo $test in the same process using exec.

$ bash -c "./test.env && exec echo $test"

c) Lastly I just tried this since it was a possible permutation. But it executes test.env and the echo command as separate processes.

$ bash -c "./test.env && echo $test"

And how can I get this to work where the env. variables are sourced before the 2nd command is executed?

share|improve this question
up vote 5 down vote accepted

You must escape dollar sign $ in your first command, otherwise bash will expand it before your command executed:

$ bash -c "source test.env && echo \$test"

Or you should use single quote instead of double quote:

$ bash -c 'source test.env && echo $test'
share|improve this answer
    
it's the simplest errors that are the most stumping – Salami Jun 8 '14 at 18:09

If the goal is only to handle setting ENV before running a process and avoiding affecting the current shell then execing the bash executable might not be the most efficient way to go about it.

( . /dev/fd/4 && echo "$i" ) 4<<\SCRIPT
    i='i is set here in the subshell'
#END
SCRIPT

echo ${i?but i isnt set here because it was set in the subshell}

OUTPUT

i is set here in the subshell
sh: line 5: i: but i isnt set here because it was set in the subshell

You can of course substitute the link to the heredoc's file-descriptor with a regular file - I just used it to demonstrate it.

But if you do exec an outside process - such as bash or any other - rather than a shell builtin then you don't need the subshell.

one=1 two=2 \
    bash -c 'echo "${cmd=This is command #}$one" 
             echo "${cmd}$two"'
echo "${one?this var was only set for the execed ENV}"

OUTPUT

This is command #1
This is command #2
sh: line 2: one: this var was only set for the execed ENV

And if that outside process is bash or any other shell conforming to the POSIX standard of accepting -stdin as default, you can just write your script directly to a |pipe file...

{ echo PS1=
  echo 'echo "$PS1"'
  cat /etc/skel/.bashrc
  echo 'echo "$PS1"'
} | bash
echo "${PS1:?unset here again}"

OUTPUT

#blank line from first echo
[\u@\h \W]\$
sh: line 7: PS1: unset here again
share|improve this answer

As written, the shell is expanding $test before it is passed to your command. You can stop this from happening by using a ' instead of ".

bash -c 'source test.env && echo $test'
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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