Reputation: 975
I'm trying to figure out why the following command only works from bash
and not from zsh
:
Bash:
bash-3.2$ eval "MYVALUE=mystring" export MYVALUE
bash-3.2$ echo $MYVALUE
mystring
Zsh:
➜ ~ eval "MYVALUE=mystring" export MYVALUE
➜ ~ echo $MYVALUE
➜
I expected zsh
to print mystring
but instead it doesn't print anything.
It looks like export
can't read the value which has just been parsed, but effectively eval
is working, because if I run this other command using zsh
:
➜ ~ eval "MYVALUE=mystring" env | grep MYVALUE
MYVALUE=mystring
it works as expected!
Can anyone please help me to figure out why the eval / export thing doesn't work with zsh
but works with bash
and how eventually make it work with zsh
too? Thank you so much!
Upvotes: 1
Views: 2274
Reputation: 975
After a bit of try and error and thanks to the hint from @glenn-jackman I can say that a possible solution that works with both bash
and zsh
is:
eval "MYVALUE=mystring"; export MYVALUE
Basically we need to add ;
before the export
Upvotes: 1
Reputation: 22356
The difference between bash and zsh in this respect is not related to eval, but in a subtle difference related to export.
You execute eval
with 3 parameter:
"MYVALUE=mystring"
export
MYVALUE
Now the zsh man page (at least of my zsh version) is a bit misleading in its description of what eval is doing when it is invoked with more than argument, but a simple experiment shows what is going on:
eval 'A=BBBBBB' 'printenv A'
outputs BBBBBB. In fact, eval seems to string its arguments together into a single string, but separates the pieces by a space. Hence in your case,
eval "MYVALUE=mystring" export MYVALU
is equivalent to
eval "MYVALUE=mystring export MYVALU"
which in turn is simply
MYVALUE=mystring export MYVALU
and here is a difference between bash and zsh:
While in both shells, a statement of the form
A=B C
executes C where in a modified environment where A is set to B, the bash export is a command and "sees" the modified environment. This means that in
A=B export A
the bash export command "sees" the setting of A and exports the variable. In zsh, the export is simply a keyword and the modified invironment is ignored.
Therefore, you need either two separate statements in zsh, for instance
eval "MYVALUE=mystring;" export MYVALUE
or rewrite it as
eval export "MYVALUE=mystring"
Of course this leaves still the question, why you are using eval in the first place.
Upvotes: 1