public note

gcloudコマンドの実行結果が標準エラー出力に流れるときの対処法

はじめに

GCP のサービスの中には、gcloud コマンドの実行結果がなぜか標準エラー出力に流れてしまうケースがあります。私が把握している限りでは、Cloud Composer がこれに該当します。

エラーハンドリングをしようとしても正常終了時のメッセージが邪魔をして、思ったような動作にならない...そんなときの対処法です。

user-output-enabled オプション を False にする

このオプションを False にすると、(本来であれば標準出力に流れるはずの)実行結果が出力されなくなります。グローバルオプションなので、Cloud Composer 以外のコマンドでも有効です。

指定方法は2通りあります。

  • --user-output-enabled=false
  • --no-user-output-enabled

これを指定した場合でも、エラーが発生した場合のメッセージは標準エラー出力へ流れますので安心です。

gcloud  |  Cloud SDK のドキュメント  |  Google Cloud

実際に試してみる

まず、--user-output-enabled=true (デフォルト)で試してみます。

require 'open3'

module GCloudTest
  module_function

  def run_cmd!(cmd)
    out, err, status = Open3.capture3(cmd)
    unless err.empty?
      puts 'This is a stderr message.'
      puts err
      exit(status.exitstatus)
    end
    puts out
    status.exitstatus
  end

  def execute
    cmd = 'gcloud composer environments list --locations=us-central1 --user-output-enabled=true --verbosity=error'
    run_cmd!(cmd)
  end
end

if __FILE__ == $PROGRAM_NAME
  status = GCloudTest.execute
  exit(status)
end
$ ruby ./gcloud_stderr.rb 
This is a stderr message.
Listed 0 items.
0

ステータスは0ですが、実行結果が標準エラー出力に流れています。

次は --user-output-enabled=false にしてみます。

(中略)
    cmd = 'gcloud composer environments list --locations=us-central1 --user-output-enabled=false --verbosity=error'
(中略)
$ ruby ./gcloud_stderr.rb 

0

実行結果を出力しなくなったので、stdout と stderr 両方とも empty になりました。

最後に、エラーを捕捉できるかを確かめるため、あえてコマンドを間違えてみます。

(中略)
    cmd = 'gcloud composer environments list --locations=us-central --user-output-enabled=false --verbosity=error'
(中略)
$ ruby ./gcloud_stderr.rb 
This is a stderr message.
ERROR: (gcloud.composer.environments.list) INVALID_ARGUMENT: Unexpected location: us-central
1

エラーを捕捉できるのを確認できました。

Issue Tracker に報告されているのだが

ちなみにこの件は、IssueTrackerにも報告されていて Fixed になっている のですが、最新の344.0.0-1 でも修正されていないようなので、再報告しようかなと思っています。

参考