为何env -i未清除显式设置的ENVFILE与COMMAND环境变量?
为什么
env -i没清除显式设置的ENVFILE和COMMAND? 嘿,这个问题的核心其实是shell参数展开的时机——你被变量替换的顺序给“骗”啦!
先拆解你这段代码的执行流程:
export local ENVFILE="$1" COMMAND="$2" /usr/bin/env -i /bin/bash -c ". ${ENVFILE}; ${COMMAND}"
(顺带提一句:export local是bash里的语法错误哦,正确写法应该是先local定义局部变量,再用export导出,不过这不影响咱们解决核心问题)
关键原因:变量展开发生在env -i执行之前
当你调用这个函数时,你的**当前shell(也就是定义这个函数的bash进程)**会先对整个命令行做参数解析和变量替换:
${ENVFILE}会被替换成你传入的第一个参数$1的实际值${COMMAND}会被替换成第二个参数$2的实际值
等这些替换完成后,才会调用env -i。也就是说,env -i启动的那个全新bash进程,拿到的是已经完全展开的命令字符串——比如你调用函数时传入的是./my.env和echo $PATH,那传给bash -c的内容已经是. ./my.env; echo $PATH,根本没有${ENVFILE}和${COMMAND}这些变量引用了!
env -i确实在清空环境,但它不需要这两个变量
env -i的作用是在完全空白的环境中启动后续的命令,但这个命令已经是展开后的结果了。ENVFILE和COMMAND这两个变量只在你的当前shell里存在,用来完成参数替换,它们根本没被传到env -i启动的bash环境里——自然也不存在被清除的说法啦。
验证一下?
你可以试试把代码改成这样,强制让变量在env -i的bash里展开:
local ENVFILE="$1" COMMAND="$2" /usr/bin/env -i /bin/bash -c '. "$ENVFILE"; "$COMMAND"'
这时候运行肯定会报错,因为env -i清空了环境,新bash里根本找不到ENVFILE和COMMAND这两个变量。
内容的提问来源于stack exchange,提问作者spoovy
相关产品推荐
相关产品推荐

