Strongbash
Различия
Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
соглашения_кода:strongbash [08.04.2018 18:23] admin |
соглашения_кода:strongbash [14.01.2020 09:26] (текущий) nikolay_carbonsoft |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | ~~NOCACHE~~ | ||
===== Соглашение по строгому 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~~ | ||