如何将 运行 "gcloud app deploy" 中的错误捕获到变量中 (Bash)

How to capture errors from running "gcloud app deploy" into a variable (Bash)

我正在通过 bash 脚本将我的应用程序部署到 GCP。我想在变量中捕获任何部署错误并在发生部署错误时执行一些操作。

我的部署命令如下所示:

gcloud app deploy --version $version --project my-app-$environment $micro.yaml --quiet $no_promote &

您可以假设此命令正在处理我传递的变量。我尝试了以下变体:

  1. var=$(...)

    var=$(gcloud app deploy --version $version --project my-app-$environment $micro.yaml --quiet $no_promote &)

    回声 ******************************
    echo "${var}"
    回声 ******************************

  2. var=`...`

    var=`gcloud app deploy --version $version --project my-app-$environment $micro.yaml --quiet $no_promote &`

    回声 ******************************
    回显 $var
    回声 ******************************

我尝试过的 GCP 方面的其他变体:

  1. --verbosity="警告"

    var=$(gcloud app deploy --version $version --project my-app-$environment $micro.yaml --quiet $no_promote --verbosity="warning" &)

  2. --verbosity="错误"

    var=$(gcloud app deploy --version $version --project my-app-$environment $micro.yaml --quiet $no_promote --verbosity="error" &)

  3. --log-http

    var=$(gcloud app deploy --version $version --project my-app-$environment $micro.yaml --quiet $no_promote --log-http &)

  4. --启用用户输出

    var=$(gcloud app deploy --version $version --project my-app-$environment $micro.yaml --quiet $no_promote --user-output-enabled &)

到目前为止我尝试过的所有操作,$var 总是返回空的。即使在部署过程中出现错误。

╔════════════════════════════════════════════════════════════╗
╠═ Uploading 0 files to Google Cloud Storage                ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
ERROR: (gcloud.app.deploy) ABORTED: Cannot operate on apps/my-app-qa/services/search/versions/1 because an operation is already in progress for apps/my-app-qa/services/search/versions/1 by 3458c670-76bd-42ec-a971-c0ceda7ef34f.
******************************    
    
******************************

当通过 bash 脚本进行部署时,有没有办法检测到 GCP 部署错误?似乎我遗漏了一些非常基本的东西,但我无法理解它。

更新:我在下面写的内容仍然有效,但我错过了主要问题:您尝试 运行 中的 gcloud 工具背景(通过其命令行末尾的 &),这意味着在 $() 构造有机会捕获任何内容之前立即调用 returns。

您实际上在做的是在命令实际有机会输出任何内容之前将命令的输出分配给您的变量。所以你基本上有两个选择:

选项 1:运行 在前台执行命令,并在脚本完成后继续执行。如果命令 运行ning 很长时间并且“后台”是故意的,这显然是行不通的。

选项 2:运行 后台命令,将其 stderr 重定向到一个文件(见下文),然后主动监视该文件的更改(即错误)。这肯定是个难题,具体的实现方式在很大程度上取决于您希望脚本执行的操作。

原答案: 我不是特别熟悉 gcloud 工具,但我假设它会将错误消息打印到 stderr(这是命令行工具的约定)。 $(command) 构造捕获 stdout,所以你得到所有 除了 错误。

要解决此问题,您必须在 gcloud 调用中重定向 stderr:

var=$(gcloud --options 2>&1)

2>&1 告诉由 $() 构造生成的嵌套 shell 将输出流 #2 (= stderr) 重定向 (>) 到同一位置(&) 作为流 #1 (= stdout),导致它被捕获到您的变量中。

由于您可能只想捕获 stderr,因此您还需要摆脱 stdout:

var=$(gcloud --options 2>&1 >/dev/null)

>/dev/null 将默认流 (= stderr) 重定向到 void。

如果您想同时显示命令输出并捕获其错误,另一种方法是将 stderr 通过管道传输到 tee(打印输入并将副本保存到文件的工具),然后读取捕获的错误文件到你的变量:

gcloud --options 2| tee /tmp/my-gcloud-errors
var=$(cat /tmp/my-gcloud-errors)

(答案可能包含错误,因为我是在我的 phone 上打字的,我腿上有一只猫。稍后会修复)