使用exec关闭动态分配文件描述符时出现“not found”错误的原因?
为什么
exec $fd<&-报错“exec: 10: not found”,而eval "exec $fd<&-"能正常关闭文件描述符? 问题场景
当用exec {fd}<>myfile打开文件并自动分配文件描述符(比如得到fd=10)后,执行exec $fd<&-试图关闭该描述符时,bash会抛出错误:exec: 10: not found,但改用eval "exec $fd<&-"就能成功关闭。
核心原因
bash对exec命令的语法解析顺序导致了这个问题:
- bash会先解析命令中的重定向语法,再处理变量展开。当你写
exec $fd<&-时,bash在解析阶段只会把<&-识别为重定向符号,但此时$fd还没被展开,它会把$fd所在的位置当成要执行的命令名。当变量展开后,$fd变成10,bash就会认为你要执行名为10的命令,同时附带<&-的重定向——但系统里不存在名为10的命令,因此报错。 - 而
eval的作用是先将整个字符串展开为完整的命令(比如exec 10<&-),再让bash重新解析这个完整命令。此时bash能正确识别10<&-是“关闭文件描述符10”的重定向操作,而非命令名,因此可以正常执行。
验证示例
- 打开文件并获取描述符:
exec {fd}<>test.txt echo $fd # 输出类似10的数字 - 直接执行报错:
exec $fd<&- # 输出:bash: exec: 10: not found - 用
eval执行成功:eval "exec $fd<&-" # 无报错,检查当前进程的文件描述符: ls -l /proc/$$/fd/ | grep $fd # 无结果,说明已关闭
内容的提问来源于stack exchange,提问作者kingkong
相关产品推荐
相关产品推荐

