RHEL6与RHEL7中tcsh sourcing文件时的错误管理差异问询
根因分析
- 不同版本tcsh的执行逻辑差异和信号处理无关,是官方版本迭代时调整了默认错误行为:
- tcsh 6.17.04及更早版本:非交互模式下默认开启错误终止逻辑,任意命令执行失败(包括未定义变量报错)都会直接终止整个shell进程,因此source foo失败后不会执行后续的source bar指令。
- tcsh 6.17.05及更新版本:官方调整了默认配置,非交互模式下单个命令失败只会返回非0退出码,不会终止整个进程,因此会继续执行source bar指令打印ok。
- 你遇到的终端被kill问题是RHEL7官方源提供的tcsh二进制包的下游补丁缺陷导致:RedHat对自带的tcsh 6.17.05版本打了自研补丁,该补丁在处理未定义变量错误时逻辑异常,会错误向当前shell进程发送SIGHUP信号触发进程终止。你自行编译的上游官方版本没有携带该下游补丁,因此不会出现崩溃问题。
无需修改baz文件的解决方案
- 方案1:对齐RHEL6的行为,开启未定义变量立即终止配置
执行命令修改为:
开启set -u; eval `cat baz`-u选项后,tcsh遇到未定义变量会直接终止进程,既和RHEL6行为一致,也不会触发后续的补丁bug导致崩溃。 - 方案2:提前兜底处理可能不存在的变量,从根源避免报错
执行命令修改为:
该命令会先检查变量是否存在,不存在则设为空值,完全避免触发未定义变量错误,自然不会走到崩溃逻辑。set UNKNOWN_VARIABLE >& /dev/null || set UNKNOWN_VARIABLE="" eval `cat baz` - 方案3:对齐上游官方版本行为
替换系统自带的tcsh二进制为你自行编译的无下游补丁的上游版本,即可保留tcsh 6.17.05的默认继续执行逻辑,同时不会出现终端崩溃问题。
内容的提问来源于stack exchange,提问作者lionelm
相关产品推荐
相关产品推荐

