Skip to main content
Skip to main content

naming-conventions

Function Names

Lower-case, with underscores to separate words. Separate libraries with ::. Parentheses are required after the function name. The keyword function is optional, but must be used consistently throughout a project.

If you're writing single functions, use lowercase and separate words with underscore. If you're writing a package, separate package names with ::. Braces must be on the same line as the function name (as with other languages at Google) and no space between the function name and the parenthesis.

# Single function
my_func() {

}

# Part of a package
mypackage::my_func() {

}

The function keyword is extraneous when "()" is present after the function name, but enhances quick identification of functions.

Functions which can only be called from a specific context, depend on a variable from the parent scope, should be named with a leading ":".

Variable Names

As for function names.

Variables names for loops should be similarly named for any variable you're looping through.

for zone in "${zones[@]}"; do
something_with "${zone}"
done

Constants and Environment Variable Names

All caps, separated with underscores, declared at the top of the file.

Constants and anything exported to the environment should be capitalized.

# Constant
readonly PATH_TO_FILES='/some/path'

# Both constant and environment
declare -xr ORACLE_SID='PROD'

Some things become constant at their first setting (for example, via getopts). Thus, it's OK to set a constant in getopts or based on a condition, but it should be made readonly immediately afterwards. For the sake of clarity readonly or export is recommended instead of the equivalent declare commands.

VERBOSE='false'
while getopts 'v' flag; do
case "${flag}" in
v) VERBOSE='true' ;;
esac
done
readonly VERBOSE

Source Filenames

Lowercase, with underscores to separate words if desired.

This is for consistency with other code styles in Google: maketemplate or make_template but not make-template.

Read-only Variables

Use readonly or declare -r to ensure they're read only.

As globals are widely used in shell, it's important to catch errors when working with them. When you declare a variable that is meant to be read-only, make this explicit.

zip_version="$(dpkg --status zip | grep Version: | cut -d ' ' -f 2)"
if [[ -z "${zip_version}" ]]; then
error_message
else
readonly zip_version
fi

Use Local Variables

Declare function-specific variables with local. Declaration and assignment should be on different lines.

Ensure that local variables are only seen inside a function and its children by using local when declaring them. This avoids polluting the global name space and inadvertently setting variables that may have significance outside the function.

Declaration and assignment must be separate statements when the assignment value is provided by a command substitution; as the local builtin does not propagate the exit code from the command substitution.

my_func2() {
local name="$1"

# Separate lines for declaration and assignment:
local my_var
my_var="$(my_func)"
(( $? == 0 )) || return


}
my_func2() {
# DO NOT do this:
# $? will always be zero, as it contains the exit code of 'local', not my_func
local my_var="$(my_func)"
(( $? == 0 )) || return


}

Function Location

Put all functions together in the file just below constants. Don't hide executable code between functions. Doing so makes the code difficult to follow and results in nasty surprises when debugging.

If you've got functions, put them all together near the top of the file. Only includes, set statements and setting constants may be done before declaring functions.

main

A function called main is required for scripts long enough to contain at least one other function.

In order to easily find the start of the program, put the main program in a function called main as the bottom most function. This provides consistency with the rest of the code base as well as allowing you to define more variables as local (which can't be done if the main code is not a function). The last non-comment line in the file should be a call to main:

main "$@"

Obviously, for short scripts where it's just a linear flow, main is overkill and so is not required.

Was this section helpful?