我试图弄清楚为什么以下命令只在bash
中有效,而在zsh
中无效:
Bash:
bash-3.2$ eval "MYVALUE=mystring" export MYVALUE
bash-3.2$ echo $MYVALUE
mystring
Zsh:
➜ ~ eval "MYVALUE=mystring" export MYVALUE
➜ ~ echo $MYVALUE
➜
我原以为zsh
会打印mystring
,但它什么也没打印。
看起来export
无法读取刚刚解析的值,但实际上eval
正在工作,因为如果我使用zsh
:运行另一个命令
➜ ~ eval "MYVALUE=mystring" env | grep MYVALUE
MYVALUE=mystring
它按预期工作!
有人能帮我弄清楚为什么eval/export东西不能用zsh
,但能用bash
,以及最终如何使它也能用zsh
吗?非常感谢!
bash和zsh在这方面的差异与eval无关,而是与导出相关的细微差异。
您使用3个参数执行eval
:
"MYVALUE=mystring"
export
MYVALUE
现在,zsh手册页(至少是我的zsh版本)在描述eval在被调用时所做的事情时有点误导,但一个简单的实验显示了正在发生的事情:
eval 'A=BBBBBB' 'printenv A'
输出BBBBBB。事实上,eval似乎将其参数串成一个字符串,但用空格分隔各个部分。因此,在您的情况下,
eval "MYVALUE=mystring" export MYVALU
相当于
eval "MYVALUE=mystring export MYVALU"
这又是简单的
MYVALUE=mystring export MYVALU
bash和zsh之间有一个区别:
在两个外壳中,形式的声明
A=B C
执行C,其中在a设置为B的修改环境中,bash导出是一个命令,并"查看"修改后的环境。这意味着在中
A=B export A
bash export命令"查看"A的设置并导出变量。在zsh中,导出只是一个关键字,而修改后的环境将被忽略。
因此,您需要在zsh中使用两个单独的语句,例如
eval "MYVALUE=mystring;" export MYVALUE
或者将其重写为
eval export "MYVALUE=mystring"
当然,这仍然留下了一个问题,为什么你首先使用eval。
经过一番尝试和错误之后,由于@glenn jackman的提示,我可以说一个既适用于bash
又适用于zsh
的可能解决方案是:
eval "MYVALUE=mystring"; export MYVALUE
基本上,我们需要在export
之前添加;