Bash Styleguide
https://google.github.io/styleguide/shellguide.html
сохраненная версия
Когда следует использовать Bash
-
начинается с
#!/bin/bash
-
Исполняемые файлы должны иметь
.sh
расширение -
использовать
set -e
в начале скрипта - Для чего использовать set -e в bash -
SUID и SGID запрещены в скриптах оболочки.
-
Все сообщения об ошибках следует отправлять по адресу
STDERR
. -
Пример:
err() {
echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $*" >&2
}
if ! do_something; then
err "Unable to do_something"
exit 1
fi
Комментарии
- Начните каждый файл с описания его содержимого
- Пример:
#!/bin/bash
#
# Perform hot backups of Oracle databases.
-
Комментируйте сложные, неочевидные, интересные или важные части вашего кода.
-
Используйте комментарии TODO для кода, который является временным, краткосрочным решением или достаточно хорошим, но не идеальным.
-
Пример:
# TODO(mrmonkey): Handle the unlikely edge cases (bug ####)
Функции
-
Любая функция, которая не является одновременно очевидной и короткой, должна иметь комментарий заголовка функции.
-
Любая функция в библиотеке должна иметь комментарий заголовка функции независимо от длины или сложности.
-
Все комментарии заголовков функций должны описывать предполагаемое поведение API, используя:
- Описание функции.
- Глобальные переменные: список используемых и измененных глобальных переменных.
- Аргументы: Аргументы приняты.
- Выходные данные: Вывод на STDOUT или STDERR.
- Возвращает: Возвращает значения, отличные от статуса выхода по умолчанию последней выполненной команды.
-
Пример:
#######################################
# Cleanup files from the backup directory.
# Globals:
# BACKUP_DIR
# ORACLE_SID
# Arguments:
# None
#######################################
function cleanup() {
…
}
#######################################
# Get configuration directory.
# Globals:
# SOMEDIR
# Arguments:
# None
# Outputs:
# Writes location to stdout
#######################################
function get_dir() {
echo "${SOMEDIR}"
}
#######################################
# Delete a file in a sophisticated manner.
# Arguments:
# File to delete, a path.
# Returns:
# 0 if thing was deleted, non-zero on error.
#######################################
function del_thing() {
rm "$1"
}
Форматирование
- Отступ 2 пробела, без табуляции
- Использовать пустые строки для улучшения читабельности
Длина строки, длинные строки
- Максимальная длина строки - 80 символов
- Слова, которые длиннее 80 символов и не могут быть разумно разделены, допустимы, но, где это возможно, эти элементы должны быть на отдельной строке или факторизованы в переменной
- обрати внимание ниже на
long_file
иlong_string_alt
- обрати внимание ниже на
- Пример
# DO use 'here document's
cat <<END
I am an exceptionally long
string.
END
# Embedded newlines are ok too
long_string="I am an exceptionally
long string."
long_file="/i/am/an/exceptionally/loooooooooooooooooooooooooooooooooooooooooooooooooooong_file"
long_string_with_long_file="i am including an exceptionally \
/very/long/file\
in this long string."
# Long file converted into a shorter variable name with cleaner line breaking.
long_string_alt="i am an including an exceptionally ${long_file} in this long\
string"
Пайпы (они же "пайплайны")
- Если все пайпы не помещаются на одной линии, их следует разделить по одному на линию.
- Если весь пайп умещается на одной линии, он должен быть на одной линии.
- Если нет, его следует разбить на сегменты с одним пайпом на строку, а на новой строке в 2 пробела для следующего раздела пайпа.
\
следует последовательно использовать для обозначения продолжения строки.- Это относится к цепочке команд, объединенных с помощью,
|
- а также к логическим соединениям с помощью
||
и&&
.
- Это относится к цепочке команд, объединенных с помощью,
- Пример:
# All fits on one line
command1 | command2
# Long commands
command1 \
| command2 \
| command3 \
| command4
Переменные
_
- можно-
- нетmission_name
- можноMISSION_NAME
- нельзя
Потоки управления
- Поместите
; then
и; do
на той же строке, что иif
,for
, илиwhile
. else
должны быть на своей собственной строке- закрывающие операторы (
fi
anddone
) должны быть на своей собственной строке
Пример:
local dir
for dir in "${dirs_to_cleanup[@]}"; do
if [[ -d "${dir}/${SESSION_ID}" ]]; then
log_date "Cleaning up old files in ${dir}/${SESSION_ID}"
rm "${dir}/${SESSION_ID}/"* || error_message
else
mkdir -p "${dir}/${SESSION_ID}" || error_message
fi
done
If
[[ ... ]]
более гибкий, поддерживает||
и&&
.[...]
требует-o
дляOR
и-a
дляAND
.