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

Ubuntu下docker compose run捕获输出致终端冻结的脚本问题

解决docker compose run捕获输出时脚本卡住的问题

问题分析

当用$()捕获docker compose run命令的输出时,脚本会卡在命令执行阶段无法继续。直接运行命令却正常,原因是docker compose run默认会分配TTY(终端),即使是非交互式场景,捕获输出时进程会因等待终端输入而挂起。

解决方案

方法1:禁用TTY分配(推荐)

给docker compose run添加-T参数,明确禁用TTY分配,让进程在无终端环境下正常执行:

#!/bin/bash

set -x

DOCKER_COMPOSE_FILE="/services/nginx/docker-compose.yml"

echo "starting renewal"

# 添加-T参数禁用TTY,避免进程挂起
output=$(/usr/bin/docker compose -f "$DOCKER_COMPOSE_FILE" run -T --rm certbot renew --force-renewal 2>&1)

echo "docker script has run"
# 此处添加发送output到日志服务商的逻辑,例如:
# curl -H "Content-Type: text/plain" -X POST -d "$output" https://your-log-provider.com/endpoint

方法2:通过临时文件中转输出

如果不想修改docker compose命令参数,可以先将输出重定向到临时文件,再读取文件内容:

#!/bin/bash

set -x

DOCKER_COMPOSE_FILE="/services/nginx/docker-compose.yml"
# 创建临时文件存储输出
TEMP_LOG=$(mktemp)

echo "starting renewal"

# 将命令输出写入临时文件
/usr/bin/docker compose -f "$DOCKER_COMPOSE_FILE" run --rm certbot renew --force-renewal 2>&1 > "$TEMP_LOG"

# 读取临时文件内容到变量
output=$(cat "$TEMP_LOG")
# 删除临时文件
rm "$TEMP_LOG"

echo "docker script has run"
# 发送output到日志服务商

额外注意事项

  • 变量引用时添加双引号(如"$DOCKER_COMPOSE_FILE"),避免路径包含空格时出现错误。
  • 如果不需要调试,可移除set -x以减少日志输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 16:03:16