Strongbash
Различия
Здесь показаны различия между двумя версиями данной страницы.
| Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
|
соглашения_кода:strongbash [08.04.2018 17:51] admin [Соглашение по строгому bash] |
соглашения_кода:strongbash [14.01.2020 09:26] (текущий) nikolay_carbonsoft |
||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| ===== Соглашение по строгому bash ===== | ===== Соглашение по строгому bash ===== | ||
| - | . | + | TODO_OSV возможно выборочно проверять номера из https://github.com/koalaman/shellcheck |
| ===== strongbash001 ===== | ===== strongbash001 ===== | ||
| Строка 102: | Строка 102: | ||
| ===== strongbash002 ===== | ===== strongbash002 ===== | ||
| - | **Должен быть установлен set -eu или include ::carbon.sys** \\ | + | **Должен быть установлен set -eu или include crab_sys.sh** \\ |
| **Категорически нельзя ставить <del>set -o pipefail</del> на весь файл см strongbash034_6** | **Категорически нельзя ставить <del>set -o pipefail</del> на весь файл см strongbash034_6** | ||
| <WRAP center round important>ВНИМАНИЕ set -eu это самое главное правило, оно дает режим strong.\\ | <WRAP center round important>ВНИМАНИЕ set -eu это самое главное правило, оно дает режим strong.\\ | ||
| Строка 201: | Строка 201: | ||
| } | } | ||
| - | ### так нельзя тк любое условие выключает set -e [ "$( check_is_oversized /tmp34/11.log )" = TRUE ] | + | ### [ "$( check_is_oversized /tmp34/11.log )" = TRUE ] --- так нельзя тк любое условие полностью выключает set -e |
| ret=$( check_is_oversized /tmp34/11.log ) ### обязательно через промежуточную переменную иначе тоже set -e потеряется | ret=$( check_is_oversized /tmp34/11.log ) ### обязательно через промежуточную переменную иначе тоже set -e потеряется | ||
| Строка 245: | Строка 245: | ||
| [ "${1:---help}" = '--help' ] && { echo 'Example: $0 src dst'; exit 0; } | [ "${1:---help}" = '--help' ] && { echo 'Example: $0 src dst'; exit 0; } | ||
| </code> | </code> | ||
| - | Или учитывая правило skill -1 надо делать так:\\ | + | Или учитывая правило skill -1 сделать так:\\ |
| <code bash> | <code bash> | ||
| [ "${1:-}" = '' -o "${1:-}" = '--help' ] && { echo 'Example: $0 src dst'; exit 0; } | [ "${1:-}" = '' -o "${1:-}" = '--help' ] && { echo 'Example: $0 src dst'; exit 0; } | ||
| Строка 280: | Строка 280: | ||
| ===== strongbash005 ===== | ===== strongbash005 ===== | ||
| **В конце каждой функции должен быть return 0 или return $ret или exit 0 или exit $ret**\\ | **В конце каждой функции должен быть return 0 или return $ret или exit 0 или exit $ret**\\ | ||
| - | <hidden Почему...>Это обязательно, чтобы не передать случайно неявное и нежелаемое значение последнего if, вместо явного.</hidden> | + | <hidden Почему...>Это обязательно, чтобы не передать случайно неявное и нежелаемое значение последнего if, вместо явного $?.</hidden> |
| <hidden Пример...> | <hidden Пример...> | ||
| <color #ed1c24>Плохо:</color> | <color #ed1c24>Плохо:</color> | ||
| Строка 306: | Строка 306: | ||
| </hidden> | </hidden> | ||
| ===== strongbash006 ===== | ===== strongbash006 ===== | ||
| - | **В начале каждого файла должен быть echo START и EXAMPLE\\ | + | **В начале каждого файла должен быть echo START и USAGE, INFO, EXAMPLE\\ |
| В конце каждого файла должны быть echo SUCCESS и exit 0 :\\ ** | В конце каждого файла должны быть echo SUCCESS и exit 0 :\\ ** | ||
| - | Для продвинутых разработчиков лучше использовать в начале скрипт: include ::carbon.sys | + | Для продвинутых разработчиков лучше использовать в начале скрипт: include crab_sys.sh |
| <hidden Почему...> | <hidden Почему...> | ||
| - exit 0 для того чтобы избежать случайный код возврата. | - exit 0 для того чтобы избежать случайный код возврата. | ||
| - | - EXAMPLE использования важен, чтобы программа могла жить в будущем и не была выборошена. | + | - USAGE, INFO, EXAMPLE использования важен, чтобы программа могла жить в будущем и не была выброшена. |
| - | - echo START echo SUCCESS делает удобным использование и чтение логов. | + | - echo START echo SUCCESS делает удобным использование и чтение консоли и логов. |
| - | - include ::carbon.sys позволит автоматически деалать echo START echo SUCCESS echo FAIL sys::usage "$@" # --help и показывает callstack при падении | + | - include crab_sys.sh позволит автоматически деалать echo START echo SUCCESS echo FAIL sys::usage "$@" # --help и показывает callstack при падении |
| </hidden> | </hidden> | ||
| <hidden Пример...> | <hidden Пример...> | ||
| Строка 320: | Строка 320: | ||
| #!/bin/bash | #!/bin/bash | ||
| echo "$0 $@ [$$] START" >&2 | echo "$0 $@ [$$] START" >&2 | ||
| - | [ "${1:---help}" = '--help' ] && { echo Example: $0 src dst; exit 0; } | + | if [ "${1:---help}" = '--help' ]; then |
| + | echo "Usage: $0 src dst" | ||
| + | echo "Example: $0 /tmp/12 /tmp/14.gz" | ||
| + | echo "Info: Копирование со сжатием" | ||
| + | exit 0 | ||
| + | fi | ||
| cmd1 | cmd1 | ||
| cmd2 | cmd2 | ||
| Строка 327: | Строка 332: | ||
| exit 0 | exit 0 | ||
| </code> | </code> | ||
| - | <color #22b14c>Хорошо если много exit 0 в программе</color> | + | <color #22b14c>Хорошо сделать функцию</color> <nowiki> |
| + | __exit()</nowiki><color #22b14c>, если много exit 0 в программе</color> | ||
| <code bash> | <code bash> | ||
| #!/bin/bash | #!/bin/bash | ||
| Строка 350: | Строка 356: | ||
| <code bash> | <code bash> | ||
| #!/bin/bash | #!/bin/bash | ||
| - | source ::carbon.sys | + | source crab_sys.sh |
| sys::usage "$@" | sys::usage "$@" | ||
| ### --help Info: Автоматически создавать и коммитить все файлы в каталоге | ### --help Info: Автоматически создавать и коммитить все файлы в каталоге | ||
| ### --help Usage: auto_git.sh [install] /var/www/html | ### --help Usage: auto_git.sh [install] /var/www/html | ||
| ### --help Example: auto_git.sh /var/www/html | ### --help Example: auto_git.sh /var/www/html | ||
| + | ### Пример sys::arg_parse "txt1" "txt2" "--named1=a1" "--named2=a2" "--forced" | ||
| + | ### Пример echo "${ARGV[1]}==txt1 ${ARGV[2]}==txt2 ${ARG_NAMED1}==a1 ${ARGV_NAMED2}==a2 ${ARG_FORCED}==TRUE" | ||
| sys::arg_parse "$@" | sys::arg_parse "$@" | ||
| cmd1 | cmd1 | ||
| Строка 367: | Строка 375: | ||
| <code bash> | <code bash> | ||
| # echo "$0 START">&2 | # echo "$0 START">&2 | ||
| + | ### --help Info: Автоматически создавать и коммитить все файлы в каталоге | ||
| + | ### --help Usage: auto_git.sh [install] /var/www/html | ||
| + | ### --help Example: auto_git.sh /var/www/html | ||
| # echo "$0 SUCCESS">&2 | # echo "$0 SUCCESS">&2 | ||
| + | exit 0 | ||
| </code> | </code> | ||
| - | <color #22b14c>Или для тихих файлов с carbon.sys:</color> | + | <color #22b14c>Или для тихих файлов с crab_sys.sh:</color> |
| <code bash> | <code bash> | ||
| __SILENT=TRUE | __SILENT=TRUE | ||
| - | source ::carbon.sys | + | source crab_sys.sh |
| + | ### --help Info: Автоматически создавать и коммитить все файлы в каталоге | ||
| + | ### --help Usage: auto_git.sh [install] /var/www/html | ||
| + | ### --help Example: auto_git.sh /var/www/html | ||
| + | exit 0 | ||
| </code> | </code> | ||
| </hidden> | </hidden> | ||
| + | |||
| ===== strongbash007 ===== | ===== strongbash007 ===== | ||
| Строка 458: | Строка 475: | ||
| </hidden> | </hidden> | ||
| - | ===== strongbash010 warning TODO ===== | + | ===== strongbash010 warning ===== |
| **Не рекомендуется использовать переменные, особенно глобальные, для временных файлов, если эта переменная используется менее 5 раз.**\\ | **Не рекомендуется использовать переменные, особенно глобальные, для временных файлов, если эта переменная используется менее 5 раз.**\\ | ||
| <del>$TMP_FILE=$( mktemp /tmp/tmp_file.XXXX )</del> | <del>$TMP_FILE=$( mktemp /tmp/tmp_file.XXXX )</del> | ||
| Строка 464: | Строка 481: | ||
| - Это усложняет чтение кода и понимание кода, файл сам по себе есть переменная и временная ссылка на него редко оправдана.\\ | - Это усложняет чтение кода и понимание кода, файл сам по себе есть переменная и временная ссылка на него редко оправдана.\\ | ||
| - Плохо если приходится искать далеко вверху по коду, что это за переменная, и что там в этом файле.\\ | - Плохо если приходится искать далеко вверху по коду, что это за переменная, и что там в этом файле.\\ | ||
| - | - mktmp это тоже плохо так как бессмысленно.\\ | + | - mktemp это тоже плохо так как бессмысленно, если оч надо <code bash> |
| - | - Имя временного файла должно содержать в себе имя исполняемой программы и ее PID обязательно.\\ | + | tt=/tmp/NAME_$((RANDOM)).$$ |
| + | </code>\\ | ||
| + | - Имя временного файла должно содержать в себе имя исполняемой программы и ее PID обязательно для разбора оставшихся после падения файлов.\\ | ||
| + | - Если файлов останется от падения слишком много, то скрипт не сможет работать тк пиды заполнятся и это нормально мы об этом узнаем. Либо можно сделать rm -f перед работой | ||
| </hidden> | </hidden> | ||
| Строка 503: | Строка 523: | ||
| </code> | </code> | ||
| - | <color #22b14c>Хорошо:</color> | + | <color #22b14c>Хорошо локальное использование:</color> |
| <code bash> | <code bash> | ||
| ls /var/lib > /tmp/myname_tmpls.$$ | ls /var/lib > /tmp/myname_tmpls.$$ | ||
| Строка 528: | Строка 548: | ||
| </code> | </code> | ||
| </hidden> | </hidden> | ||
| + | ### todo http://opencarbon.ru/соглашения_кода:strongbash_коменты | ||
| ===== strongbash011 ===== | ===== strongbash011 ===== | ||
| **Максимальный indent вложенность 5**\\ | **Максимальный indent вложенность 5**\\ | ||
| Строка 533: | Строка 554: | ||
| Большая вложенность всегда приводит к большой вложенности мысли при чтении кода, это неудобно и приводит к ошибкам.\\ | Большая вложенность всегда приводит к большой вложенности мысли при чтении кода, это неудобно и приводит к ошибкам.\\ | ||
| Используйте ранний return или сделайте подфункции, или case и тп.\\ | Используйте ранний return или сделайте подфункции, или case и тп.\\ | ||
| - | Не используйте большие if then else и мозг будет занят 5-ю уровнями вложенности.\\ | + | Не используйте большие if then else иначе мозг будет занят 5-ю уровнями вложенности.\\ |
| </hidden> | </hidden> | ||
| Строка 573: | Строка 594: | ||
| **Слишком большой линейный файл больше 64 строк, выделите подфункции.** | **Слишком большой линейный файл больше 64 строк, выделите подфункции.** | ||
| <hidden Почему...> | <hidden Почему...> | ||
| - | Если в файле больше 64 строк, значит однозначно есть команды которые делают похожие вещи и правильней их объединить в функции.\\ | + | Если в файле больше 64 строк, значит однозначно есть команды которые делают похожие вещи или группу вещей и правильней их объединить в функции.\\ |
| </hidden> | </hidden> | ||
| ===== strongbash016 ===== | ===== strongbash016 ===== | ||
| Строка 598: | Строка 619: | ||
| echo "aaaaaaaaaaaaaaaaaaaaaa\ | echo "aaaaaaaaaaaaaaaaaaaaaa\ | ||
| bbbbbbbbbbbbbbbbbbb" | bbbbbbbbbbbbbbbbbbb" | ||
| + | или | ||
| + | txt=\ | ||
| + | "aaaaaaaaaaaaaaaaaaaaaa | ||
| + | bbbbbbbbbbbbbbbbbbb" | ||
| + | или | ||
| iptables -t nat -I xge_pre -m addrtype ! --dst-type LOCAL \ | iptables -t nat -I xge_pre -m addrtype ! --dst-type LOCAL \ | ||
| -m set ! --match-set xge_auth_list src \ | -m set ! --match-set xge_auth_list src \ | ||
| Строка 625: | Строка 650: | ||
| fi | fi | ||
| </code> | </code> | ||
| - | <color #22b14c>Хорошо при include ::carbon.sys</color> | + | <color #22b14c>Хорошо при include crab_sys.sh</color> |
| <code bash> | <code bash> | ||
| sys::usage "$@" и | sys::usage "$@" и | ||
| Строка 649: | Строка 674: | ||
| 1. Создание временного файла это своего рода with file и его удаление это end with, чтоб было понтяно где он более не нужен аля область работы с файлом. И если файл остался в тмп, то это признак что есть ошибка в логике. | 1. Создание временного файла это своего рода with file и его удаление это end with, чтоб было понтяно где он более не нужен аля область работы с файлом. И если файл остался в тмп, то это признак что есть ошибка в логике. | ||
| - | 2. Использование trap EXIT тк он скрывает ошибки программ и никто о них не узнает, ломает честную логику алгоритма, это вредный хак. Должен быть явный вызов error_exit() и тп. | + | 2. Использование trap EXIT плохо тк он скрывает ошибки программ и никто о них не узнает, ломает честную логику алгоритма, это вредный хак. Должен быть явный вызов error_exit() и тп. |
| Если нужно удалить lock можно использовать trap TERM INT HUP, если lock остался после сбоя значит он и должен остаться, чтобы получить ошибки и разобраться со сбоем.\\ | Если нужно удалить lock можно использовать trap TERM INT HUP, если lock остался после сбоя значит он и должен остаться, чтобы получить ошибки и разобраться со сбоем.\\ | ||
| </hidden> | </hidden> | ||
| Строка 662: | Строка 687: | ||
| **2. А для чтения целой строки while <color #ed1c24>IFS=<nowiki>''</nowiki></color> read -r line; do**\\ | **2. А для чтения целой строки while <color #ed1c24>IFS=<nowiki>''</nowiki></color> read -r line; do**\\ | ||
| <hidden Почему...> | <hidden Почему...> | ||
| - | 1. read -r иначе все esc последовательности обработаются, это вряд ли Вы хотели.\\ | + | 1. read -r иначе все esc последовательности обработаются, это вряд ли то что Вы хотели.\\ |
| 2. IFS=<nowiki>''</nowiki> иначе начальные пробелы и табы потеряются и строка будет не та, что в оригинале.\\ | 2. IFS=<nowiki>''</nowiki> иначе начальные пробелы и табы потеряются и строка будет не та, что в оригинале.\\ | ||
| </hidden> | </hidden> | ||
| Строка 782: | Строка 807: | ||
| ===== strongbash029 ===== | ===== strongbash029 ===== | ||
| - | **Если мы берем stdout от функции мы обязаны прописать в первой строке set -e тк он снимается** | + | **Если мы берем stdout от функции мы обязаны прописать в первой строке Функции set -e тк он снимается** |
| - | ===== strongbash030 ===== | + | |
| - | **Нельзя вызывать функцию внутри if fname и fname&& и fname||** | + | |
| + | |||
| + | ===== strongbash030 ===== | ||
| + | **Нельзя вызывать функцию внутри if fname и fname&& и fname||**\\ | ||
| + | тк set -e перестанет работать, перевыставить не поможет | ||
| ===== strongbash031 ===== | ===== strongbash031 ===== | ||
| **нельзя использовать -EOF, используйте обычный EOF** | **нельзя использовать -EOF, используйте обычный EOF** | ||
| Строка 804: | Строка 831: | ||
| **2. set -o pipefail не работает в if $cmd; then и не нужно выставлять**\\ | **2. set -o pipefail не работает в if $cmd; then и не нужно выставлять**\\ | ||
| нет смысла выставлять перед if\\ | нет смысла выставлять перед if\\ | ||
| - | **3. Команда используется внутри pipe, ее код возврата не будет проанализирован**\\ | + | **3. ipret=$(ip r g |grep src) Команда используется внутри pipe, ее код возврата не будет проанализирован**\\ |
| <hidden Что делать> | <hidden Что делать> | ||
| Вы можете:\\ | Вы можете:\\ | ||
| Строка 827: | Строка 854: | ||
| ** Нельзя использовать присвоение внутри if a=$(cmd); then **\\ | ** Нельзя использовать присвоение внутри if a=$(cmd); then **\\ | ||
| + | ===== strongbash036 todo ===== | ||
| + | Все аргументы нужно сохранять в глобальные переменные вида <code bash> | ||
| + | ARG_MYNAME=${1//--myname=/} | ||
| + | </code>\\ | ||
| + | или sys:parse_arg "$@" | ||
| + | ===== strongbash037 todo ===== | ||
| + | Запрещено использовать echo Без кавычек | ||
| + | <del>echo $tmp</del> | ||
| + | |||
| + | |||
| + | ===== strongbash038 todo ===== | ||
| + | Нужно всегда использовать переменные и аргументы в кавычках. | ||
| + | <code bash> | ||
| + | Нельзя: | ||
| + | if [ $1 = info ]; then | ||
| + | echo $1 | ||
| + | fi | ||
| + | |||
| + | Нужно: | ||
| + | if [ "$1" = 'info' ]; then | ||
| + | echo "$1" | ||
| + | fi | ||
| + | </code> | ||
| + | |||
| + | |||
| ===== TODO добавить в инструкцию как программировать на баше ===== | ===== TODO добавить в инструкцию как программировать на баше ===== | ||
| + | А пока читать коменты в http://opencarbon.ru/правила_разработки:как_надо_делать:разбор_crab_mysqldump2git | ||
| + | |||
| **TODO** Описать виды функций __funct funct и виды переменных ARG CONF GLOBAL local и namespace сабшелы\\ | **TODO** Описать виды функций __funct funct и виды переменных ARG CONF GLOBAL local и namespace сабшелы\\ | ||
| **TODO** | **TODO** | ||
| В файл примера | В файл примера | ||
| - | <code bash> | ||
| - | iptables -t nat -I xge_pre -m addrtype ! --dst-type LOCAL \ | ||
| - | -m set ! --match-set xge_auth_list src \ | ||
| - | -m set ! --match-set xge_auth_list dst -j RETURN | ||
| - | </code> | ||
| Добавить в описание правил что grep -qm1 может уронить левую часть если это долгая команда и отгрепается первая строка пример | Добавить в описание правил что grep -qm1 может уронить левую часть если это долгая команда и отгрепается первая строка пример | ||
| Строка 853: | Строка 902: | ||
| {(rater>id=1|name=Прочитал_соглашения_кода:strongbash|type=vote|trace=user|tracedetails=1)} | {(rater>id=1|name=Прочитал_соглашения_кода:strongbash|type=vote|trace=user|tracedetails=1)} | ||
| + | |||
| + | ~~OWNERAPPROVE~~ | ||