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

Bash中使用exec通过变量关闭文件描述符报not found错误

问题根因

报错核心是Shell命令解析顺序的优先级规则:Shell会先识别命令里的重定向语法,再执行变量展开。
你写exec $fd<&-时,Shell在重定向解析阶段看到<&-前面是变量$fd而非字面量数字,就不会把这段识别为关闭文件描述符的重定向操作。等变量展开完成后,整行被解析为exec 25 <&-,25被当成exec要执行的外部命令,Shell找不到名为25的可执行文件,就抛出exec: 25: not found错误。
另外你的fd存储逻辑还有隐藏bug:Bash数组追加元素的写法错误,fds+=$pfd不会新增数组元素,只会把$pfd拼接到数组第一个元素末尾,后续循环读取时会拿到拼接后的错误fd值。

修复方案

1. 修正数组追加语法

把原有fds+=$pfd替换为标准数组追加写法,保证每个fd作为独立元素存储:

fds+=("$pfd")

2. 动态操作文件描述符的正确写法

由于重定向解析早于变量展开,动态指定fd编号时需要用eval提前构造完整命令,让Shell能正确识别重定向规则:

修复后的fd关闭逻辑

for fd in "${fds[@]}"; do
    echo "Closing fd $fd and remove pipes"
    eval "exec $fd<&-"
    rm -f "pipe$fd"
done

如果关闭的是写端文件描述符,把<&-替换为>&-即可,和你打开fd时的读写方向保持一致。

修复后的fd创建逻辑参考

pfd=25 # 从25开始分配fd,避开程序自身占用的描述符
fds=()
mkfifo "pipe$pfd"
eval "exec $pfd>pipe$pfd"
fds+=("$pfd")
pfd=$((pfd + 1))

内容的提问来源于stack exchange,提问作者Remy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 10:31:02