1

I have a bash script like

# print.sh
# export FOO=test would work too
FOO=test ./foo-proj # Something that cares about FOO (shell script or just a binary)

This works. However, I'm wondering why if I do this...

#print.sh
blah="FOO=test"
$blah ./foo-proj

I get this error ./print.sh: line 2: FOO=test: command not found. It's like bash is now interpreting FOO=test as a command instead of a variable declaration. Is there any way around this?

1
  • Welcome, you can do for example FOO=echo; blah=FOO; ${!blah} foo → foo, but I don't know if that's what you aim to. Commented Feb 2, 2022 at 16:59

2 Answers 2

3

Some options:

env -- "$blah" ./foo-proj

There, that's env that calls ./foo-proj with the contents of $blah in its environment. The advantage is that variable names in that case are not limited to valid shell variable names. For instance, you could have blah='+++=xxx' to pass an environment variable called +++ even though +++ is not a valid shell variable name.

(export -- "$blah"; exec ./foo-proj)

Or:

eval  " $blah ./foo-proj"

Where eval will be passed " FOO=test ./foo-proj" as one argument, and that string will then be evaluated as shell code (where the = will then be literal and therefore treated as an assigment).

Beware though that if $blah is blah='FOO=test;reboot;', it will reboot for instance.

2
  • I've found using bash -c "$blah ./foo-proj" works too. Is this equivalent to eval? Commented Feb 3, 2022 at 15:39
  • 1
    That's like eval, but has the code run by a new separate invocation of the bash interpreter instead of the current one. So it's about as dangerous and less efficient. Commented Feb 3, 2022 at 15:45
1

I think that in your case, bash doesn't detect the $blah as an environment variable, but rather as a command containing a =.

You need to do something like :

blah="test"
FOO=$blah ./foo-proj

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.