如何用新终端(TTY)进入已经在运行的 Docker 容器?

docker exec -it 容器名 sh(或 bash)为运行中的容器开一个新终端会话;exit 通常只结束新 shell,但会话内命令仍可影响共享状态。本文说明参数含义与无 shell 镜像的替代方案。

最佳实践
如何用新终端(TTY)进入已经在运行的 Docker 容器?封面

一条命令:docker exec -it <容器名或ID> sh——在运行中的容器里新起一个带 TTY 的交互 shell。有 bash 的镜像(Ubuntu/Debian 系)可用 bash 体验更好;退出输 exit,只结束这个 shell,容器主进程不受影响。

参数拆解

docker exec -it myapp bash
  • -i:保持 stdin 打开(能输入)
  • -t:分配伪终端(终端设备语义;提示符/补全取决于shell)
  • 两个合起来才是完整的交互终端

成功后提示符类似 root@f3a2b1c9:/#,此时就在容器里了。

常用变体

# 以 root 身份进入(容器默认用户无权限时)
docker exec -u 0 -it myapp sh

# 以指定用户进入
docker exec -u www-data -it myapp sh

# 只跑一条命令不开终端
docker exec myapp cat /etc/app/config.yml

没有 bash/sh 怎么办

极简镜像(alpine 有 sh;distroless、scratch 连 sh 都没有)进不去时的替代:

docker cp myapp:/app/logs ./logs        # 拷文件出来看
docker diff myapp                        # 看文件系统改动
docker logs myapp                        # 看输出

K8s 场景可用 kubectl debug 给 Pod 挂一个带工具的临时容器。

exec vs attach 再强调

exec 是新进程,仍共享文件、网络与应用状态,执行命令可能影响主进程;attach 是接主进程,Ctrl+C 会误停容器。进容器排查永远用 exec。

exec 默认继承容器创建时的环境配置,可用 -e 覆盖本次进程;不会自动继承PID1后来export的变量。镜像是否有bash/sh取决于实际内容,不能仅按发行版名称保证。

常见问题(FAQ)

Q:报 "container is not running"?
A:容器已停止(docker ps -a 确认),exec只能在运行且未暂停的容器执行,生命周期依赖主进程;docker start 后再进。

Q:进去之后很多命令找不到?
A:精简镜像只装运行必需的东西;apt/apk 现装,或改用拷文件出来的方式。

Q:能同时开多个 exec 会话吗?
A:可以,但共享状态可能互相影响。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台