Bash Shell中变量拼接目录路径写入文件时报路径不存在错误
Bash 脚本动态拼接路径失效问题排查
核心根因
从你贴的报错文本的错位顺序,可以直接确认异常来源:逐行读取得到的$line变量末尾携带了Windows格式的不可见回车符(\r,即CR控制字符)。
正常无异常的路径,拼接后系统尝试打开的是/test/sensor/test1/test.txt,报错应该完整显示为/test/sensor/test1/test.txt: No such file or directory。但因为路径里混了不可见的\r,这个字符会强制把终端光标拉回当前行开头,后续输出的报错文本会覆盖掉路径的前半段,最终在屏幕上就呈现出你看到的错位效果。
这个问题完全匹配你描述的所有现象:
- 硬编码写死路径时,路径里没有这个隐藏字符,所以脚本执行完全正常
- 2019年脚本可运行,是因为当时的输入文件是纯Linux标准LF换行格式;现在这份
/test/sensor/test文件大概率是从Windows环境拷贝、编辑后存为CRLF换行格式,带了多余的回车符 - 哪怕你把权限、目录、目标文件都配置完全正确,只要路径里混了不可见的
\r,系统就无法识别到真实的目录层级,报找不到路径的错误
快速验证方法
在脚本的循环逻辑里加一行调试输出,把变量里的不可见字符打印出来确认:
while IFS= read -r line; do # 打印当前行的所有字符,包括控制符 echo "调试行内容:[$line]" | cat -A done < "$input"
如果输出里看到行尾带有^M标识(这就是\r的终端显示形式),比如显示为test1^M,就100%确认是换行符不兼容的问题。
对应修复方案
两种常用处理方式,按需选择即可:
- 不需要修改原输入文件,直接在脚本逻辑里加一行过滤,把读取到的行尾残留回车符清掉就行:
while IFS= read -r line; do # 移除行尾所有可能残留的\r字符 line=${line%$'\r'} # 拼接路径时给变量加引号,避免路径带空格时出现解析异常 echo "worked" >> "/test/sensor/${line}/test.txt" done < "$input"
- 如果是长期复用的输入文件,也可以直接把源文件转成Linux标准格式,执行
dos2unix /test/sensor/test完成格式转换后,原脚本不需要做任何修改就能正常运行。
排障提醒
- 不要为了快速排障长期给目录、文件开777权限,临时验证可以,生产环境很容易引入安全风险
- 处理这类带不可见控制字符的问题时,优先用
cat -A、od -c这类工具查看原始字节,不要靠肉眼观察文本内容判断
内容的提问来源于stack exchange,提问作者hjq92402
相关产品推荐
相关产品推荐

