Shell脚本如何获取JS执行时设置的环境变量值
问题原因
环境变量是进程私有资源,遵循进程隔离规则:父进程启动子进程时,会把自己的环境变量拷贝给子进程,但子进程运行过程中对自身环境变量做的任何修改,都只会保存在子进程自己的内存空间里,不会反向同步回父进程。
你在JS插件里写的process.env['INCREMENTED_VERSION'] = incrementedVersion,修改的是sls命令启动的Node.js子进程自身的环境变量,等sls deploy执行完、Node进程退出后,这个变量就跟着进程一起销毁了,外层的deploy.sh作为父进程根本拿不到这个值。
解决方法
子进程的变量没法直接回传父进程,只能通过进程间通信的方式传递值,下面是两种最常用的实现:
方案1:通过标准输出传递(推荐)
修改JS插件逻辑,在拿到incrementedVersion值后,把它按约定格式打印到标准输出,shell脚本里捕获sls命令的输出,过滤出需要的版本值即可。
- JS插件新增输出逻辑,为了避免和sls本身的日志混淆,建议加特殊前缀:
// 原有逻辑保留 process.env['INCREMENTED_VERSION'] = incrementedVersion // 新增输出版本值的逻辑,加特殊标记方便过滤 console.log(`SLS_INCREMENTED_VERSION_OUTPUT:${incrementedVersion}`)
- 修改deploy.sh的逻辑,捕获输出并过滤版本号:
# 执行sls deploy,同时从输出中过滤出标记的版本值 INCREMENTED_VERSION=$(sls deploy | grep -oP 'SLS_INCREMENTED_VERSION_OUTPUT:\K.*') echo "Incremented version is " echo ${INCREMENTED_VERSION}
方案2:通过临时文件传递
如果不想改动sls的原有输出逻辑,可以让JS插件把版本值写到约定好的临时文件里,shell执行完sls后直接读取文件内容即可。
- JS插件新增写文件逻辑:
const fs = require('fs') // 原有逻辑保留 process.env['INCREMENTED_VERSION'] = incrementedVersion // 把版本值写入临时文件 fs.writeFileSync('/tmp/.sls_incremented_version_cache', incrementedVersion)
- 修改deploy.sh逻辑,执行完部署后读文件:
sls deploy # 从临时文件读取版本值 INCREMENTED_VERSION=$(cat /tmp/.sls_incremented_version_cache) # 用完删除临时文件,避免残留 rm -f /tmp/.sls_incremented_version_cache echo "Incremented version is " echo ${INCREMENTED_VERSION}
注意:不要尝试在JS子进程里调用
export类的命令设置环境变量,这类操作只会影响JS进程启动的更下一级子进程,依然无法回传到外层的父shell。
内容的提问来源于stack exchange,提问作者systemdebt
相关产品推荐
相关产品推荐

