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

为何Docker不为CMD打开新的文件描述符fd?

问题分析与解决

问题根源

你遇到的报错是因为本地Shell提前解析了重定向参数,导致容器内的进程没有正确创建并继承文件描述符fd3。

当执行docker run --rm -v$PWD:$PWD -w$PWD ubuntu sh run.sh 3>&1 >/dev/null时,重定向逻辑是被你的本地Shell处理的:

  • 本地Shell会先将容器进程的stdout(fd1)重定向到/dev/null
  • 本地Shell创建的fd3并不会被Docker传递到容器内部——Docker默认仅保留stdin、stdout、stderr三个文件描述符,其他未明确指定的fd会被强制关闭。
    因此容器内的run.sh尝试写入fd3时,就会触发"Bad file descriptor"错误。

解决方法

方法1:让容器内的Shell处理重定向

把包含重定向的命令用sh -c包裹,让容器内部的Shell来解析重定向参数,确保fd3在容器内正确创建:

docker run --rm -v$PWD:$PWD -w$PWD ubuntu sh -c "./run.sh 3>&1 >/dev/null"

此时容器内的Shell会先将fd3复制为当前的stdout(最终关联到你的终端),再将stdout重定向到/dev/null,run.sh里的echo Hello from me >&3就能正常输出到终端。

方法2:修改脚本兼容fd3不存在的情况

在run.sh开头添加检查逻辑,确保fd3始终处于可用状态(若未打开则绑定到stdout),这样不管是本地还是Docker环境都能兼容:

#!/bin/sh
# 确保fd3已打开,若未打开则绑定到stdout
[ -w /dev/fd/3 ] || exec 3>&1

echo No hello from me!
echo Hello from me >&3

修改后,直接执行原Docker命令即可得到预期输出:

docker run --rm -v$PWD:$PWD -w$PWD ubuntu sh run.sh 3>&1 >/dev/null

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 08:35:03