Running bash scripts

This page explains how to configure Cloud Build to run bash scriptswithin a build step. If you're new to Cloud Build, read thequickstarts and theBuild configuration overview first.

You can run bash scripts within a build step to configure a number of workflowsincluding:

  • Running multiple commands in one build step.
  • Reading from the filesystem.
  • Building in logic such as retries or conditionals.
  • Outputting to the log, for example, runningecho $VARNAME.

Using thescript field

Cloud Build provides ascript field that you can use to specifyshell scripts to execute in a build step. Thescript field takes a single stringvalue.

You can prefix the string value with ashebang to specify the shell to interpret the script. For example, add#!/usr/bin/env bash tospecify the Bash shell. If you don't prefix the script string with a shebang, Cloud Build uses#!/bin/sh which is the basic sh shell, not Bash shell.

If you specifyscript in a build step, you cannot specifyargs orentrypointin the same step.

The following snippet demonstrates thescript field:

YAML

steps:-name:'bash'script:|#!/usr/bin/env bashecho "Hello World"-name:'ubuntu'script:echo hello-name:'python'script:|#!/usr/bin/env pythonprint('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"}]}

Using substitutions with thescript field

Scripts don't directly support substitutions, but they support environmentvariables. You can map substitutions to environment variables, eitherautomatically all at once, or manually by defining every environment variableyourself.

Map substitutions automatically

  • At the build level. To automatically map all the substitutions toenvironment variables, which will be available throughout the entire build,setautomapSubstitutions totrue as an option at the build level. Forexample, the following build config file shows the user-definedsubstitution$_USER and the default substitution$PROJECT_ID mapped toenvironment variables:

    YAML

    steps:-name:'ubuntu'script:|#!/usr/bin/env bashecho "Hello $_USER"-name:'ubuntu'script:|#!/usr/bin/env bashecho "Your project ID is $PROJECT_ID"options:automapSubstitutions:truesubstitutions:_USER:"GoogleCloud"

    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"}}
  • At the step level. To automatically map all the substitutions and makethem available as environment variables in a single step, set theautomapSubstitutions field totrue in that step. In the followingexample, only the second step will show the substitutions correctly,because it's the only one with automatic substitutions mapping enabled:

    YAML

    steps:-name:'ubuntu'script:|#!/usr/bin/env bashecho "Hello $_USER"-name:'ubuntu'script:|#!/usr/bin/env bashecho "Your project ID is $PROJECT_ID"automapSubstitutions:truesubstitutions:_USER:"GoogleCloud"

    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"}

    Additionally, you can make the substitutions available as environmentvariables in the entire build, then ignore them in one step. SetautomapSubstitutions totrue at the build level, then set the samefield tofalse in the step where you want to ignore the substitutions. Inthe following example, even though mapping substitutions is enabled at thebuild level, the project ID will not be printed in the second step, becauseautomapSubstitutions is set tofalse in that step:

    YAML

    steps:-name:'ubuntu'script:|#!/usr/bin/env bashecho "Hello $_USER"-name:'ubuntu'script:|#!/usr/bin/env bashecho "Your project ID is $PROJECT_ID"automapSubstitutions:falseoptions:automapSubstitutions:truesubstitutions:_USER:"GoogleCloud"

    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"}

Map substitutions manually

You can manually map the substitutions to environment variables. Everyenvironment variable is defined at the step level usingtheenvfield, and the scope of the variables is restricted to the stepwhere they are defined. This field takes a list of keys and values.

The following example shows how to map the substitution$PROJECT_ID to theenvironment variableBAR:

YAML

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

JSON

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

Running bash scripts on disk

If you have your bash script saved in a file, store the file along withyour build source, and reference the script file within your build config file:

YAML

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

JSON

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

To use a bash script on file if bash is not the default entrypoint of the imageyou're using, add anentrypoint field pointing to bash:

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"]}]}

Running inline bash scripts

To run bash commands using thebash image, specifybash as thenameof the build step, and the command in the args field:

YAML

steps:-name:'bash'args:['echo','Iamrunningabashcommand']

JSON

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

If the image you're using comes prepackaged withbash but ifbash is not thedefault entrypoint, add anentrypoint field pointing tobash. In the examplebelow, thebash entrypoint is used to rungcloud commands that queryCloud Build for build status, listing builds with a failed status.

YAML

steps:-name:'gcr.io/google.com/cloudsdktool/cloud-sdk'entrypoint:'bash'args:-'-eEuo'-'pipefail'-'-c'-|-gcloud builds list > builds.txtwhile read line; doif grep -q "FAILURE" <<< "$line"; thenecho "$line"fidone < 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"]}]}

The-c flag in the code above is used to execute multi-line commands. Any stringyou pass after-c is treated as a command. For more information on running bashcommands with-c, see thebash documentation.

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.