You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在可被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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:00:05