当我从 docker img 中写入时,写入文件为空

write to file is empty when I write from within a docker img

下面的代码是 MakeFile 的一部分,在 ci/cd 中的某个阶段 运行 时执行。

.PHONY:deploy_endpoint_configuration
deploy_endpoint_configuration: 
    @echo Deploying endpoint configuration
    gcloud endpoints services deploy ocr/model_adapter/predict_contracts.yaml --project $(project) &> $(project_dir)/deploy_contract.txt
    cat $(project_dir)/deploy_contract.txt | grep -Eo '\d*-\d*-\w*' | tail -n1 > $(project_dir)/config_id.txt

我遇到的是当这段代码在管道(例如GitLab)中执行时,deploy_contract.txt等的内容总是空的。我不明白为什么?这与 MakeFile 为每个命令执行新的 shell 这一事实有关吗?虽然不完全确定,但这很难调试。当我 运行 如下所示时,我确实确认了这个问题:gitlab-运行ner exec docker - 这里是阶段 - (用于本地调试目的)。但是当我 运行 它在 macOS 上本地运行时(即只执行 make deploy_endpoint_configuration),因此它不像以前那样包装在容器中,它 运行s 和它应该的功能(读作config_id 和 deploy_contract 的内容不为空但包含 stdout + errorout)

供参考: ci/cd 阶段使用的图像 = 图像:dsl.company.com:5000/python:3.7-buster 最重要的是安装了 gcloud cli 以使用 gcloud 命令。

有人知道为什么没有内容写入我的文件吗? (虽然肯定会部署 - 所以一定有东西)

我怀疑这是因为您的命令脚本依赖于 bash 功能。 GNU make 总是 运行 /bin/sh 作为它的 shell。在某些系统(如 RedHat 和 RedHat-derived 系统)上,/bin/sh 实际上是 link 到 bash,因此使用 bash 特定功能的 makefile 配方将起作用。我相信 MacOS 做同样的事情,虽然我不做 Mac.

在其他系统上,像 Debian 和 Debian-derived 像 Ubuntu 的系统,/bin/sh 是一个简单、快速的 POSIX-compliant shell 像 dash,它不支持花哨的 bash 内容,因此使用 bash 特定功能的 makefile 配方将不起作用。

可能您的容器映像是后一种类型,而 MacOS(您的本地系统)使用 bash 作为 shell。

您正在使用 &>,这是一项 bash-specific 功能,POSIX shells 不支持该功能。

您应该使用 POSIX 语法编写此代码,即 >$(project_dir)/deploy_contract.txt 2>&1

或者您可以尝试覆盖您的 makefile 中的 shell:

SHELL := /bin/bash

强制 make 改为 运行 bash...只要您 运行ning 的容器镜像确实有 bash它。