Running bash scripts Stay organized with collections Save and categorize content based on your preferences.
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, running
echo $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,set
automapSubstitutionstotrueas an option at the build level. Forexample, the following build config file shows the user-definedsubstitution$_USERand the default substitution$PROJECT_IDmapped 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 the
automapSubstitutionsfield totruein 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. Set
automapSubstitutionstotrueat the build level, then set the samefield tofalsein 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, becauseautomapSubstitutionsis set tofalsein 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.txtJSON
{"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
- Learn how tostart a build manually.
- Learn how toautomate builds using triggers.
- Learn how toconfigure build step order.
- Learn how touse community-contributed builders and custom builders.
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.