Skip to content

Shell scripts#

This page describes the rules for shell scripts in Autoware. pre-commit checks each script with ShellCheck and formats it with shfmt.

References#

Follow the Google Shell Style Guide when this page does not define a rule:

Use Bash#

Write scripts for Bash. Start each script with a shebang line:

#!/usr/bin/env bash

#!/bin/bash is also used, for example in docker/docker-entrypoint.sh. If a script must run in sh, use only POSIX features in it.

Stop on errors#

Put set -euo pipefail after the shebang and the header comment:

  • -e stops the script when a command fails.
  • -u stops the script when it uses a variable that is not set.
  • -o pipefail makes a pipeline fail when any command in it fails, not only the last command.

For example, ansible/scripts/install-ansible.sh starts with:

#!/usr/bin/env bash
# Install Ansible (and its OS prerequisites) so that the playbooks under
# autoware/ansible/ can be run.
# ...

set -euo pipefail

If a command can fail and the script must continue, handle the failure on that line, for example with || true.

ShellCheck#

pre-commit checks all shell scripts with ShellCheck. Fix every warning. For example, ShellCheck warns about a variable without quotes (SC2086). Put variables in double quotes, for example "${HOST_UID}", so that a value with spaces stays one argument.

If a warning is a false positive, add a # shellcheck directive on the line before the command. A directive such as # shellcheck disable=SC2012 turns off one check for that command. Write the reason in a comment above the directive. As another example, docker-entrypoint.sh sources a file that ShellCheck cannot read, so it tells ShellCheck not to follow the file:

# shellcheck source=/dev/null
source "/opt/ros/${ROS_DISTRO}/setup.bash"

The autoware repository has a .shellcheckrc file with external-sources=true. With this option, ShellCheck follows the files that a script sources.

shfmt#

pre-commit formats all shell scripts with shfmt and these options:

- repo: https://github.com/scop/pre-commit-shfmt
  hooks:
    - id: shfmt
      args: [-w, -s, -i=4]
  • -w writes the result to the file.
  • -s simplifies the code, for example it removes unnecessary $ in arithmetic expressions.
  • -i=4 indents with four spaces.

Thus, indent shell scripts with four spaces, not with tabs.

Style#

  • Give functions and variables snake_case names. Give environment variables and constants UPPER_SNAKE_CASE names.
  • Use "${var}" with braces for variables in strings.
  • Use $(command) for command substitution, not backticks.
  • Send error messages to standard error, for example echo "error: file not found" >&2.
  • If a script needs root permissions for some commands, use sudo for those commands only. Do not run the whole script as root.