執行 bash 指令碼

本頁說明如何設定 Cloud Build,在建構步驟中執行 bash 指令碼。如果您是 Cloud Build 新手,請先參閱快速入門導覽課程建構設定總覽

您可以在建構步驟中執行 bash 指令碼,設定多個工作流程,包括:

  • 在一個建構步驟中執行多個指令。
  • 從檔案系統讀取。
  • 建構重試或條件式等邏輯。
  • 輸出至記錄檔,例如執行 echo $VARNAME

使用 script 欄位

Cloud Build 提供 script 欄位,可用於指定要在建構步驟中執行的殼層指令碼。script 欄位會採用單一字串值。

您可以在字串值前面加上 shebang,指定要用來解譯指令碼的殼層。舉例來說,您可以新增 #!/usr/bin/env bash指定 Bash 殼層。如果沒有在指令碼字串加上 Shebang 前置字串,Cloud Build 會使用 #!/bin/sh,這是基本的 sh shell,而非 Bash shell。

如果在建構步驟中指定 script,則無法在同一個步驟中指定 argsentrypoint

下列程式碼片段示範 script 欄位:

YAML

steps:
- name: 'bash'
  script: |
    #!/usr/bin/env bash
    echo "Hello World"
- name: 'ubuntu'
  script: echo hello
- name: 'python'
  script: |
    #!/usr/bin/env python
    print('hello from python')

JSON

{
  "steps": [
  {
    "name": "bash",
    "script": "#!/usr/bin/env bash echo 'Hello World'"
  },
  {
    "name": "ubuntu",
    "script": "echo hello"
  },
  {
    "name": "python",
    "script": "#!/usr/bin/env python\nprint('hello from python')\n"
  }
  ]
}

搭配 script 欄位使用 substitutions

指令碼不直接支援替代,但支援環境變數。您可以將替代項目對應至環境變數,方法是自動一次完成所有對應,或是手動定義每個環境變數。

自動對應替代字元

  • 在建構層級。如要自動將所有替代項目對應至環境變數,並在整個建構過程中提供這些變數,請在建構層級將 automapSubstitutions 設為 true 選項。舉例來說,下列建構設定檔顯示對應至環境變數的使用者定義替代項目 $_USER 和預設替代項目 $PROJECT_ID

    YAML

    steps:
    - name: 'ubuntu'
      script: |
        #!/usr/bin/env bash
        echo "Hello $_USER"
    - name: 'ubuntu'
      script: |
        #!/usr/bin/env bash
        echo "Your project ID is $PROJECT_ID"
    options:
      automapSubstitutions: true
    substitutions:
      _USER: "Google Cloud"
    

    JSON

    {
      "steps": [
        {
          "name": "ubuntu",
          "script": "#!/usr/bin/env bash echo 'Hello $_USER'"
        },
        {
          "name": "ubuntu",
          "script": "#!/usr/bin/env bash echo 'Your project ID is $PROJECT_ID'"
        }
      ],
      "options": {
        "automap_substitutions": true
      },
      "substitutions": {
        "_USER": "Google Cloud"
      }
    }
    
  • 在步驟層級。如要自動對應所有替代項目,並在單一步驟中將這些項目設為環境變數,請在該步驟中將 automapSubstitutions 欄位設為 true。在下列範例中,只有第二個步驟會正確顯示替換內容,因為只有這個步驟啟用自動替換對應:

    YAML

    steps:
    - name: 'ubuntu'
      script: |
        #!/usr/bin/env bash
        echo "Hello $_USER"
    - name: 'ubuntu'
      script: |
        #!/usr/bin/env bash
        echo "Your project ID is $PROJECT_ID"
      automapSubstitutions: true
    substitutions:
      _USER: "Google Cloud"
    

    JSON

    {
      "steps": [
        {
          "name": "ubuntu",
          "script": "#!/usr/bin/env bash echo 'Hello $_USER'"
        },
        {
          "name": "ubuntu",
          "script": "#!/usr/bin/env bash echo 'Your project ID is $PROJECT_ID'",
          "automap_substitutions": true
        }
      ],
      },
      "substitutions": {
        "_USER": "Google Cloud"
      }
    

    此外,您也可以在整個建構作業中,將替代項目設為環境變數,然後在一個步驟中忽略這些變數。在建構層級將 automapSubstitutions 設為 true,然後在要忽略替代項的步驟中,將相同欄位設為 false。在下列範例中,即使在建構層級啟用對應替換,專案 ID 也不會在第二個步驟中列印,因為 automapSubstitutions 在該步驟中設為 false

    YAML

    steps:
    - name: 'ubuntu'
      script: |
        #!/usr/bin/env bash
        echo "Hello $_USER"
    - name: 'ubuntu'
      script: |
        #!/usr/bin/env bash
        echo "Your project ID is $PROJECT_ID"
      automapSubstitutions: false
    options:
      automapSubstitutions: true
    substitutions:
      _USER: "Google Cloud"
    

    JSON

    {
      "steps": [
        {
          "name": "ubuntu",
          "script": "#!/usr/bin/env bash echo 'Hello $_USER'"
        },
        {
          "name": "ubuntu",
          "script": "#!/usr/bin/env bash echo 'Your project ID is $PROJECT_ID'",
          "automap_substitutions": false
        }
      ],
      "options": {
        "automap_substitutions": true
      },
      },
      "substitutions": {
        "_USER": "Google Cloud"
      }
    

手動對應替代變數

您可以手動將替代項目對應至環境變數。每個環境變數都是在步驟層級使用env 欄位定義,且變數的範圍僅限於定義變數的步驟。這個欄位會採用鍵和值的清單。

以下範例說明如何將替代項目 $PROJECT_ID 對應至環境變數 BAR

YAML

steps:
- name: 'ubuntu'
  env:
  - 'BAR=$PROJECT_ID'
  script: 'echo $BAR'

JSON

{
  "steps": [
    {
      "name": "ubuntu",
      "env": [
        "BAR=$PROJECT_ID"
      ],
      "script": "echo $BAR"
    }
  ]
}

在磁碟上執行 bash 指令碼

如果已將 Bash 指令碼儲存在檔案中,請將該檔案與建構來源一併儲存,並在建構設定檔中參照該指令碼檔案:

YAML

steps:
- name: 'bash'
  args: ['./myscript.bash']

JSON

{
  "steps": [
  {
    "name": "bash",
    "args": [
      "./myscript.bash"
     ]
  }
  ]
}

如果 Bash 不是所用映像檔的預設進入點,如要在檔案中使用 Bash 指令碼,請新增指向 Bash 的 entrypoint 欄位:

YAML

steps:
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args: ['tools/myScript.sh','--foo']

JSON

{
  "steps": [
  {
    "name": "gcr.io/cloud-builders/gcloud",
    "entrypoint": "bash",
    "args": [
      "tools/myScript.sh",
      "--foo"
    ]
  }
  ]
}

執行內嵌 bash 指令碼

如要使用 bash 映像檔執行 bash 指令,請將 bash 指定為建構步驟的 name,並在 args 欄位中指定指令:

YAML

steps:
- name: 'bash'
  args: ['echo', 'I am running a bash command']

JSON

{
  "steps": [
    {
      "name": "bash",
      "args": [
        "echo",
        "I am running a bash command"
       ]
    }
  ]
}

如果您使用的映像檔已預先封裝 bash,但 bash 不是預設進入點,請新增指向 bashentrypoint 欄位。在下列範例中,bash 進入點用於執行 gcloud 指令,查詢 Cloud Build 的建構狀態,並列出狀態為失敗的建構作業。

YAML

steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  entrypoint: 'bash'
  args:
  - '-eEuo'
  - 'pipefail'
  - '-c'
  - |-
    gcloud builds list > builds.txt
    while read line; do
        if grep -q "FAILURE" <<< "$line"; then
            echo "$line"
        fi
    done < builds.txt

JSON

{
  "steps": [
  {
    "name": "gcr.io/google.com/cloudsdktool/cloud-sdk",
    "entrypoint": "bash",
    "args": [
      "-eEuo",
      "pipefail",
      "-c",
      "gcloud builds list > builds.txt\nwhile read line; do\n    if grep -q \"FAILURE\" <<< \"$line\"; then\n        echo \"$line\"\n    fi\ndone < builds.txt"
    ]
  }
  ]
}

上述程式碼中的 -c 旗標用於執行多行指令。-c 後方傳遞的任何字串都會視為指令。如要進一步瞭解如何使用 -c 執行 Bash 指令,請參閱 Bash 說明文件

後續步驟