Docker compose run 捕获 .sh 脚本的输出冻结终端

问题描述 投票:0回答:1

我在 Ubuntu 中有服务器。在服务器上我安装了

docker compose
(v2.29.7)。我创建了脚本
ssl-renew.sh
通过 crontab 定期更新 certbot 证书。 Certbot 通过 docker 运行的方式与我的 nginx 相同,它们位于相同的
docker-compose.yml

我没有“docker-compose”,因为它给了我这个错误:

DockerException: Error while fetching server API version: HTTPConnection.request()
,并且修复已明确说明here - 只需移至最新的“docker compose”而不带破折号

问题是当我尝试捕获输出时,“docker compose”版本不起作用。

脚本失败的部分:

#!/bin/bash

set -x

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

echo "starting renewal"

output=$(/usr/bin/docker compose -f $DOCKER_COMPOSE_FILE run --rm certbot renew --force-renewal 2>&1)

echo "docker script has run"

输出始终相同:

+ DOCKER_COMPOSE_FILE=/services/nginx/docker-compose.yml
+ echo 'starting renewal'
starting renewal
++ /usr/bin/docker compose -f /services/nginx/docker-compose.yml run --rm certbot renew --force-renewal

它永远不会达到

echo "docker script has run"
。当我删除脚本中的这一行时,该命令不是交互式的:

#output=$(/usr/bin/docker compose -f $DOCKER_COMPOSE_FILE run --rm certbot renew --force-renewal 2>&1)
/usr/bin/docker compose -f $DOCKER_COMPOSE_FILE run --rm certbot renew --force-renewal

正在工作:

+ DOCKER_COMPOSE_FILE=/services/nginx/docker-compose.yml
+ echo 'starting renewal'
starting renewal
+ /usr/bin/docker compose -f /services/nginx/docker-compose.yml run --rm certbot renew --force-renewal
WARN[0000] /services/nginx/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Renewing an existing certificate for example.com
Failed to renew certificate example.com with error: urn:ietf:params:acme:error:rateLimited

现在它运行命令并且终端没有冻结,但我想捕获输出并通过 API 将其发送到日志记录提供程序。我目前尝试了 Google 和 GPT 中的所有方法,但没有任何帮助。如果您有任何建议,我将不胜感激。

docker shell docker-compose sh
1个回答
0
投票

有几点需要注意。

您正在使用命令替换,如下所示

output=$(/usr/bin/docker compose -f $DOCKER_COMPOSE_FILE run --rm certbot renew --force-renewal 2>&1)

Bash 通过在子 shell 环境中执行命令并将命令替换替换为命令的标准输出来执行扩展,并删除所有尾随换行符。

命令替换重新分配一个命令甚至多个命令的输出;它实际上将命令输出插入到另一个上下文中

在您的情况下,您将

$()
中命令的输出分配给变量名称
output
。如果您要打印
output
变量的值(例如
echo "$output"
),您将看到内部
$()
命令的输出,例如
docker compose

当我将脚本中的行删除到这一行时......它正在工作

从您共享的输出来看,它似乎没有“工作”,因为它仍然无法打印

+ echo "docker script has run"

这意味着

docker compose
不会终止,并且脚本永远不会到达
echo "docker script has run"
行。

© www.soinside.com 2019 - 2024. All rights reserved.