如何用新终端(TTY)进入已经在运行的 Docker 容器?
docker exec -it 容器名 sh(或 bash)为运行中的容器开一个新终端会话;exit 通常只结束新 shell,但会话内命令仍可影响共享状态。本文说明参数含义与无 shell 镜像的替代方案。
一条命令: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:可以,但共享状态可能互相影响。