如何在可被source的Shell脚本中返回指定值并清除_rc、_was_sourced变量?
问题:消除脚本source后残留的
_rc和_was_sourced变量 背景
我有一个可在bash或ksh中被source(.命令),或直接在bash中执行的脚本:
- 脚本将期望的返回码存储在
${_rc}变量中; - 直接执行
return $_rc会导致_rc变量残留到终端环境; - 若在
return前unset _rc,会覆盖返回码导致无法正确返回; - 脚本未被source时必须用
exit而非return,否则会触发报错。
当前脚本末尾代码
cleanup_script # 该函数会unset所有变量,除了_rc和_was_sourced if [ "${_was_sourced}" == 1 ]; return ${_rc} else exit ${_rc} fi
测试现象
执行以下命令测试source后的环境变量变化:
typeset > before.txt . ./myscript echo $? typeset > after.txt diff before.txt after.txt
diff结果显示,除了预期保留的脚本定义变量和函数外,终端中额外残留了两个变量:
226a236 > _rc=0 232a243 > _was_sourced=1
需要完全消除这两个残留变量。
解决方案
方案1:局部变量中转(bash/ksh通用)
先将_rc和_was_sourced的值转移到临时变量,再执行cleanup清空所有变量,最后用临时变量的值完成返回:
# 保存目标变量的值到临时变量 _temp_rc=${_rc} _temp_sourced=${_was_sourced} # 执行cleanup,此时可以安全unset包括_rc、_was_sourced在内的所有变量 cleanup_script # 根据source状态执行返回/退出 if [ "${_temp_sourced}" == 1 ]; then return ${_temp_rc} else exit ${_temp_rc} fi
原理:临时变量_temp_rc和_temp_sourced仅在脚本执行周期内存在,当脚本source执行完毕后会被当前shell自动清理,不会残留到终端环境。
方案2:bash专属优化(用local变量)
在bash中,用local声明的变量属于脚本局部作用域,脚本执行结束后自动销毁,可进一步简化:
# 将变量转为局部作用域 local _local_rc=${_rc} _local_sourced=${_was_sourced} # 执行cleanup清空所有全局变量 cleanup_script # 用局部变量完成返回逻辑 if [ "${_local_sourced}" == 1 ]; then return ${_local_rc} else exit ${_local_rc} fi
方案3:return前即时清理(极简写法)
针对source场景,先保存返回码,清理变量后再执行return;非source场景下exit后变量自然消失,无需额外处理:
if [ "${_was_sourced}" == 1 ]; then # 保存返回码,清理变量后返回 local _temp_rc=${_rc} unset _rc _was_sourced return ${_temp_rc} else # 直接退出,变量不会残留到终端 exit ${_rc} fi
内容的提问来源于stack exchange,提问作者guest
相关产品推荐
相关产品推荐

