为什么cd命令会导致exec设置的shell输出重定向失效?
问题根因分析
你遇到的问题和cd破坏exec重定向无关,核心原因是你使用相对路径创建临时文件,工作目录切换后相对路径的指向发生了变化,导致写入的文件和最终读取的文件不是同一个。
具体执行流程拆解
- 脚本启动后在初始运行目录(示例中的
/script/run/path)执行mktemp,生成的$tmpfile是相对路径值,格式为.tmp.test-broken.sh.xxxxxx,此时临时文件被创建在初始运行目录下。 - 紧接着执行无参数的
cd命令,默认切换到当前用户的家目录(如/home/你的用户名),脚本的当前工作目录已变更。 - 循环中执行
exec >> "$tmpfile"时,系统会将相对路径的$tmpfile解析为当前工作目录(家目录)下的同名文件,所有echo "$var: line in file"的输出都写入了家目录下的临时文件,和你一开始在初始目录创建的临时文件没有关系。 - 脚本末尾执行
cd -切回初始运行目录,EXIT触发的cleanup函数读取的是初始目录下从未被写入的临时文件,所以输出为空。你可以去当前用户的家目录找到存有内容的临时文件。
修复方案
只要保证临时文件的路径在整个脚本生命周期内指向固定位置即可,常见方案如下:
- 方案1:创建临时文件时直接生成绝对路径,推荐优先使用系统临时目录:
# 写法1:指定/tmp作为父目录,生成绝对路径临时文件 tmpfile=$(mktemp /tmp/.tmp.$(basename $0).XXXXXX) # 写法2:将生成的相对路径转为绝对路径 tmpfile=$(realpath $(mktemp .tmp.$(basename $0).XXXXXX)) - 方案2:如果必须使用当前运行目录存储临时文件,将重定向逻辑放在
cd操作之前,或者切换回原目录后再执行写入操作。
内容的提问来源于stack exchange,提问作者azzid
相关产品推荐
相关产品推荐

