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:
-estops the script when a command fails.-ustops the script when it uses a variable that is not set.-o pipefailmakes 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]
-wwrites the result to the file.-ssimplifies the code, for example it removes unnecessary$in arithmetic expressions.-i=4indents with four spaces.
Thus, indent shell scripts with four spaces, not with tabs.
Style#
- Give functions and variables
snake_casenames. Give environment variables and constantsUPPER_SNAKE_CASEnames. - 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
sudofor those commands only. Do not run the whole script as root.