Strongbash Коменты

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
корзина:strongbash_коменты [11.03.2018 18:49]
admin [strongbash027]
корзина:strongbash_коменты [20.05.2019 15:18] (текущий)
Строка 1: Строка 1:
-===== Соглашение по строгому bash ===== +старые не обработанные коменты
- +
-===== strongbash001 ===== +
-**Обязательно должен быть выполнен crab_indent**. +
-<hidden Почему...>​ +
-  - indent делает код более читаемым +
-  - использование indent позволяет обнаруживать ошибки +
-</​hidden>​ +
-<hidden Пример...>​ +
-Конструкция **if-then** располагаются в одной строке.\\ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-if [ "​$EUID"​ -ne "​0"​ ]; then +
-      echo "​Please run as root"​ +
-fi +
-</​code>​ +
- +
- +
-Фигурная скобка **"​{"​** для определния тела функции должна быть в одной строке с функцией.\\ +
-После переноса строки добавляем **<​Tab>​**.\\ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-myfunc1() { +
-      commands... +
-+
-</​code>​ +
- +
-Объявление функции без ключевого слова **function**.\\ +
-Ключевое слово function ​было введено в ksh.\\ +
-POSIX стандартизирует только синтаксис funcname().\\ +
-Код в скобках с отступами.\\ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-myfunc1() { +
-      echo "Hello world"​ +
-+
-</​code>​ +
- +
-<color #​ed1c24>​Плохо:</​color>​ +
-<code bash> +
-function myfunc1 { +
-      echo "Hello world"​ +
-+
-</​code>​ +
- +
-Инструкция **case ** без оступов:​\\ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-case "​$variable"​ in +
-"​$condition1"​ ) +
-      command... +
-      ;; +
- +
-"​$condition2"​ ) +
-      command... +
-      ;; +
- +
-esac +
-</​code>​\\ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-#​!/​usr/​bin/​env bash +
- +
-set -euEo pipefail +
- +
-func1(){ +
-        grep '​zzz'​ /​tmp/​temp1.tmp | cat \ +
-                | grep zza \ +
-                && echo zzz || echo aaa +
-        return 0 +
-+
- +
-if func1; then +
-        echo true +
-else +
-        echo false +
-fi +
- +
-+
-        cd /tmp/ +
-        ls +
-) \ +
-| ( +
-        while read t; do +
-                echo $t +
-        done +
-  ) +
- +
-case "​${2:​-bash}"​ in +
-bash) +
-        echo bash +
-        ;; +
-*) +
-        echo "not supported yet. plz add new style"​ +
-        ;; +
-esac +
- +
-exit 0 +
-</​code>​ +
-</​hidden>​ +
- +
-===== strongbash002 ===== +
-**Должен быть установлен set -euEo pipefail или include ::​carbon.sys** \\ +
-<WRAP center round important>​ВНИМАНИЕ set -eu это самое главное правило,​ оно дает режим strong.\\ +
-Позволяет отлавливать и исключать неявное и непредсказуемое поведение программы,​ а также быстрей отлаживать.\\ +
-</​WRAP>​ +
-<WRAP center round important>​ +
-ОЧЕНЬ БОЛЬШОЕ ВНИМАНИЕ set -eu используется для того, чтобы отловить неизвестные **будущие** ошибки программы и не дать ей выполняться далее.\\ +
-set -eu **не должен** использоваться для реализации какой либо логики основного алгоритма.\\ +
-</​WRAP>​ +
-<hidden Что включает...>​ +
-set -e падать если есть необработанные ошибки,​ а точнее необработанный код возврата.\\ +
-set -u падать если используется неинициализированная переменная.\\ +
-set -o pipefail ​ падать в ERR если в одной из пайп команд произошла ошибка.\\ +
-set -E наследовать trap в функциях.\\ +
-</​hidden>​ +
-<hidden Как не надо делать...>​ +
-Todo вынести в отдельное правило\\ +
-<color #​ed1c24>​Плохо делать ассерты вида:</​color>​\\ +
-<code bash> +
-[ $# = 3 ] +
-</​code>​ +
-<color #​22b14c>​Хорошо явно отлавливать и писать текстом пользователю о **заранее** известных ошибках:</​color>​\\ +
-<code bash> +
-[ $# != 3 ] && { echo '​Укажите 3 параметра';​ exit 1; } +
-</​code>​ +
-<color #​ed1c24>​Плохо **пытаться** использовать возможности set -e для формирования кода возврата функций:</​color>​ +
-<code bash> +
-set -e +
-func1(){ +
-        grep qqq /​tmp/​myqqq.txt  +
-        # ^^^ не надо надеяться на то, что здесь упадет и функция вернет не ноль, здесь не остановится выполнение функции. +
-        # такой подход технически невозможен ни с ни без set -e +
-        return 0 +
-+
-### это работать не будет +
-func1 && echo "qqq найден"​ +
-</​code>​ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-func1(){ +
-        set -e ### требуется указать еще раз чтоб работало ret=$( func1 ) +
-        grep qqq /​tmp/​myqqq.txt && echo TRUE || echo FALSE +
-        return 0 +
-+
-ret="​$(func1)"​ +
-[ "​$ret"​ = "​TRUE"​ ] && echo "qqq найден"​ +
-</​code>​ +
-</​hidden>​ +
-<hidden Проблемы и решения set -euEo pipefail...>​ +
-<WRAP center round info> +
-set -euEo pipefail дает огромную пользу для предсказуемости работы и отладки,​ +
-но есть небольшие побочки,​ которые легко решаются.\\ +
-</​WRAP>​ +
-<color #​ed1c24>​Проблема pipefail иногда мешает делать grep:</​color>​\\ +
-<code bash> +
-set -euEo pipefail +
-# grep myssh Упадет если нет слова myssh, хотя мы может этого не хотели,​ а хотели пустой файл +
-ps aux | grep -v grep | grep myssh >/​tmp/​tmp1; ​ echo ret=$?; +
-</​code>​  +
-<color #​22b14c>​Решение,​ добавить || true :</​color>​ +
-<code bash> +
-set -euEo pipefail  +
-ps aux | grep -v grep | grep myssh >/​tmp/​tmp1 || true;  echo ret=$?; +
-</​code>​  +
-\\ +
-<color #​ed1c24>​Проблема,​ если мы вызываем функцию и анализируем ее код возврата\\ +
-в ней перестает работать set -e :</​color>​\\ +
-<code bash> +
-set -e +
-check_is_oversized(){ +
-       # set -e здесь бесполезно добавлять +
-       [ `stat -c %s $1` -gt 1000 ] && return 1 # если программа stat упадет?​ то ошибки не будет тк set -e здесь выключен уже +
-       # в итоге вернется return 0 даже если stat упал +
-       ​return 0 +
-+
-check_is_oversized /​tmp34/​11.log && echo "​файл слишком большой"​ ### команда '&&'​ отключит обработку ошибок функции check_is_oversized +
-</​code>​ +
-<color #​22b14c>​Решение,​ можно использовать echo TRUE вместо return 0 :</​color>​\\ +
-<code bash> +
-set -e +
-check_is_oversized(){ +
-       set -e  ### обязательно еще раз тк он снимется при ret=$( check_is_oversized ) +
-       [ `stat -c %s $1` -gt 1000 ] && echo TRUE +
-       echo FALSE +
-       ​return 0 +
-+
-### обязательно через промежуточную переменную иначе тоже set -e потеряется +
-### не будет работать [ "$( check_is_oversized /​tmp34/​11.log )" = TRUE ] +
-ret=$( check_is_oversized /​tmp34/​11.log ) +
-[  "​$ret"​ = TRUE ] && ​ echo "​файл слишком большой"​ +
-### Из минусов такого подхода это запуск сабшела и небольшой оверхед,​ +
-### поэтому при массовых(10000) вызовах ​ функции приходится ее использовать с потерей контроля ошибок и обычным return +
-### или можно использовать глобальную переменную ERRNO= или глобальную FNAME_RET= +
-### или работать процедурно через eval:  funct_search txt1 txt2 rettxt1 ​  ​funct_search () { eval "​$3"​='​$value'​ } +
-</​code>​\\ +
-<color #​ed1c24>​Плохо использовать</​color>​ +
-Такую конструкцию для запуска вложенных функций-команд с отловом кода возврата и без потери set -e, тк не удовлетворяет правилу skill-1 и pl7 +
-<code bash> +
-( set +e; (set -e; fun1; ); ret=$?; ); +
-</​code>​ +
-\\ +
-<color #​ed1c24>​Проблема set -u иногда непривычен для входящих параметров:</​color>​\\ +
-<code bash> +
-src=$1 ​  # если $1 не передан,​ то программа упадет +
-</​code>​ +
-<color #​22b14c>​Решение,​ можно использовать default значения переменных:</​color>​ +
-<code bash> +
-echo ${1:​-defaulttxt} +
-</​code>​ +
-<code bash> +
-[ "​${1:​---help}"​ = '​--help'​ ] && { echo '​Example:​ $0 src dst'; exit 0; } +
-</​code>​ +
-Или учитывая правило skill -1 надо делать так:\\ +
-<code bash> +
-[ "​${1:​-}"​ = ''​ -o "​${1:​-}"​ = '​--help'​ ] && { echo '​Example:​ $0 src dst'; exit 0; } +
-или +
-my_src="​${1:​-}"​ +
-</​code>​ +
-</​hidden>​ +
-===== strongbash003 ===== +
- +
-**Нельзя использовать || true в условных выражениях.**\\ +
- +
-<hidden Почему...>​Это миф что без них не работает и все падает при set -e.\\ +
-Все отлично работает,​ если return 0 в конце каждой функции и exit 0 в конце каждого файла.</​hidden>​ +
-<hidden Пример...>​ +
-<color #​ed1c24>​Как не надо делать:</​color>​ +
-<code bash> +
-funct1(){ +
-        [ a = b ] && echo Привет || true +
-+
-</​code>​ +
-<color #​22b14c>​Как надо делать:</​color>​ +
-<code bash> +
-funct1(){ +
-        [ a = b ] && echo Привет +
-        return 0 +
-+
-</​code>​ +
-</​hidden>​ +
-===== strongbash004 ===== +
- +
-**Нельзя использовать else true в условных выражениях**\\ +
-см strongbash003 +
- +
-===== strongbash005 ===== +
-**В конце каждой функции должен быть return 0 или return $ret или exit 0 или exit $ret**\\ +
-<hidden Почему...>​Это обязательно,​ чтобы не передать случайно неявное ​ и нежелаемое значение последнего if, вместо явного.</​hidden>​ +
-<hidden Пример...>​ +
-<color #​ed1c24>​Плохо:</​color>​ +
-<code bash> +
-prepare_text(){ +
-        local text="​${1:​-}"​ +
-        [ "​$text"​ = ""​ ] && echo "​Привет"​  +
-        ### "​вот здесь мы отловили код возврата и не должны упасть,​ но мы упадем сразу после выхода из функции"​ +
-        ### тк вернется последний код возврата +
-}; +
-arg1=$( prepare_text "​555"​ ) +
-echo $arg1 +
-</​code>​ +
- +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-prepare_text(){ +
-        local text="​${1:​-}"​ +
-        [ "​$text"​ = ""​ ] && echo "​Привет"​  +
-        return 0   ### мы всегда явно задаем,​ что мы хотим вернуть либо return 0 либо return $ret +
-}; +
-arg1=$( prepare_text "​555"​ ) +
-echo $arg1 +
-</​code>​ +
-</​hidden>​ +
-===== strongbash006 ===== +
-**В начале каждого файла должен быть echo START и EXAMPLE\\ +
-В конце каждого файла должны быть echo SUCCESS и exit 0 :\\ ** +
-Для продвинутых разработчиков лучше использовать в начале скрипт:​ include ::​carbon.sys +
-<hidden Почему...>​ +
-  - exit 0 для того чтобы избежать случайный код возврата. +
-  - EXAMPLE использования важен, чтобы программа могла жить в будущем и не была выборошена. +
-  - echo START echo SUCCESS делает удобным использование и чтение логов. +
-  - include ::​carbon.sys позволит автоматически деалать echo START echo SUCCESS echo FAIL sys::usage "​$@"​ # --help и показывает callstack при падении +
-</​hidden>​ +
-<hidden Пример...>​ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-#​!/​bin/​bash +
-echo "$0 $@ [$$] START" >&​2 +
-[ "​${1:​---help}"​ = '​--help'​ ] && { echo Example: $0 src dst; exit 0; } +
-cmd1 +
-cmd2 +
-cmd3 +
-echo "$0 $@ [$$] SUCCESS"​ >&​2 +
-exit 0 +
-</​code>​ +
-<color #​22b14c>​Хорошо если много exit 0 в программе</​color>​ +
-<code bash> +
-#​!/​bin/​bash +
-echo "$0 $@ [$$] START" >&​2 +
-[ "​${1:​---help}"​ = '​--help'​ ] && { echo Example: $0 src dst; exit 0; } +
-ARGV="​$@"​ +
-__exit(){ +
-        local ret=$1 +
-        [ "​$ret"​ = 0 ] && echo "$0 $ARGV [$$] SUCCESS"​ >&2 \ +
-                || echo "$0 $ARGV [$$] FAILED"​ >&​2 +
-        exit $ret +
-+
- +
-cmd1 +
-cmd2 || __exit 0 +
-cmd3 +
-echo "$0 $@ [$$] SUCCESS"​ >&​2 +
-exit 0 +
-</​code>​ +
- +
-<color #​22b14c>​Хорошо для продвинутых и для карбон софт:</​color>​ +
-<code bash> +
-#​!/​bin/​bash +
-source ::​carbon.sys +
-sys::usage "​$@"​ +
-### --help Info: Автоматически создавать и коммитить все файлы в каталоге +
-### --help Usage: auto_git.sh [install] /​var/​www/​html +
-### --help Example: auto_git.sh /​var/​www/​html +
-sys::​arg_parse "​$@"​ +
-cmd1 +
-cmd2 +
-cmd3 +
-exit 0 +
-</​code>​ +
-</​hidden>​ +
- +
-<hidden Решение проблем...>​ +
-<color #​22b14c>​Хорошо для тихих файлов:</​color>​ +
-<code bash> +
-# echo "$0 START">&​2 +
-# echo "$0 SUCCESS">&​2 +
-</​code>​ +
- +
- +
-<color #​22b14c>​Или для тихих файлов с carbon.sys:</​color>​ +
-<code bash> +
-__SILENT=TRUE +
-source ::​carbon.sys +
-</​code>​ +
-</​hidden>​ +
-===== strongbash007 ===== +
- +
-**В конце каждого файла должен быть exit 0 или для библиотек:​ # exit 0.** +
-<hidden Почему...>​ +
-Мы должны явно задавать все легальные выходы из программы аналогично как с функциями.\\ +
-exit 0 в отличии от exit $ret дополнительно защитит от будущих ошибок при рефакторинге кода.\\ +
-</​hidden>​ +
-<hidden Пример...>​ +
-<color #​22b14c>​Хорошо</​color>​ +
-<code bash> +
-#​!/​bin/​bash +
-echo "$0 $@ [$$] START" >&​2 +
-cmd1  +
-[ $sz -gt 110 ] && { echo "​Ошибка sz=$sz";​ exit 2; } +
-cmd2 +
-cmd3 +
-echo "$0 $@ [$$] SUCCESS"​ >&​2 +
-exit 0 +
-</​code>​ +
-<color #​ed1c24>​Плохо exit $ret тк в будущем при рефакторинге может появиться неоднозначности</​color>​ +
-<code bash> +
-#​!/​bin/​bash +
-echo "$0 $@ [$$] START" >&​2 +
-cmd1  +
-[ $sz -gt 110 ] && { echo "​Ошибка sz=$sz";​ exit 2; } +
-cmd2 +
-cmd3 || ret=$? +
-echo "$0 $@ [$$] SUCCESS"​ >&​2 +
-exit $ret +
-</​code>​ +
- +
-<color #​22b14c>​Хорошо. Если Ваш файл должен возвращать разные коды легально,​ то нужно это сделать явно : +
-</​color>​ +
-<code bash> +
-#​!/​bin/​bash +
-echo "$0 $@ [$$] START" >&​2 +
-cmd1 +
-ret=1 +
-ret=4 +
-ret=2 +
-echo "$0 $@ [$$] SUCCESS"​ >&​2 +
-[ $ret != 0 ] && exit $ret +
-exit 0 +
-</​code>​ +
-</​hidden>​ +
- +
-===== strongbash008 ===== +
- +
-**Нужно использовать shebang #!/bin/bash и даже в include**\\  +
-**Не нужно использовать shebang переносимости <​del>#​!/​usr/​bin/​env bash</​del>​** +
-<hidden Почему...>​ +
-1. Позволит проверять include на crab_syntax\\ +
-2. #​!/​usr/​bin/​env не нужно использовать для /bin/bash тк 99,999 ОС linux bash лежит в /bin/bash и только если Вы хотите использовать код на не linux, тогда возможно потребуется /​usr/​bin/​env\\ +
-</​hidden>​ +
-<hidden Пример...>​ +
-<color #​ed1c24>​Плохо</​color>​ +
-<code bash> +
-#​!/​usr/​bin/​env bash +
-</​code>​ +
-<color #​22b14c>​Хорошо</​color>​ +
-<code bash> +
-#​!/​bin/​bash +
-</​code>​ +
-</​hidden>​ +
-===== strongbash009 ===== +
- +
-**Нельзя использовать команду let.** +
-<hidden Почему...>​ +
-Так как она дает ошибку при переходе через 0, let i=1-1 упадет скрипт. +
-</​hidden>​ +
-<hidden Пример...>​ +
-Плохо:​ +
-<code bash> +
-let c=a-b +
-</​code>​ +
-Хорошо:​\\ +
-<code bash> +
-c=$((a-b)) +
-</​code>​ +
-</​hidden>​ +
- +
-===== strongbash010 warning TODO ===== +
-**Не рекомендуется использовать переменные,​ особенно глобальные,​ для временных файлов,​ если эта переменная используется менее 5 раз.**\\ +
-<​del>​$TMP_FILE=$( mktemp /​tmp/​tmp_file.XXXX )</​del>​ +
-<hidden Почему...>​ +
-  - Это усложняет чтение кода и понимание кода, файл сам по себе есть переменная и временная ссылка на него редко оправдана.\\ +
-  - Плохо если приходится искать далеко вверху по коду, что это за переменная,​ и что там в этом файле.\\ +
-  - mktmp это тоже плохо так как бессмысленно.\\ +
-  - Имя временного файла должно содержать в себе имя исполняемой программы и ее PID обязательно.\\ +
-</​hidden>​ +
- +
-<hidden Пример...>​ +
-<color #​ed1c24>​Плохо тк используется мало и глобальная переменная:</​color>​ +
-<code bash> +
-$TMP_FILE_CAT_FROM=/​tmp/​${binname}_tmpls.$$ ​ или ​ $TMP_FILE_CAT_FROM=$( mktemp /​tmp/​tmpls.XXXX ) +
-ls /var/lib > $TMP_FILE_CAT_FROM +
-while read f; do +
-        echo $f +
-done < $TMP_FILE_CAT_FROM +
-rm -f $TMP_FILE_CAT_FROM +
-</​code>​ +
-<color #​ed1c24>​Плохо тк используется далеко от объявления и глобальная переменная:</​color>​ +
-<color #​ed1c24>​(Иногда это нормально для временных каталогов)</​color>​ +
-<code bash> +
-$TMP_FILE_CAT_FROM=/​tmp/​${binname}_tmpls.$$ ​ или ​ $TMP_FILE_CAT_FROM=$( mktemp /​tmp/​tmpls.XXXX ) +
-код1 +
-код2 +
-код3 +
-код4 +
-код5 +
-код6 +
-ls /var/lib > $TMP_FILE_CAT_FROM +
-while read f; do +
-        echo $f +
-done < $TMP_FILE_CAT_FROM +
-ls /var/lib > $TMP_FILE_CAT_FROM +
-while read f1; do +
-        echo $f1 +
-done < $TMP_FILE_CAT_FROM +
-ls /var/lib > $TMP_FILE_CAT_FROM +
-while read f2; do +
-        echo $f2 +
-done < $TMP_FILE_CAT_FROM +
-rm -f $TMP_FILE_CAT_FROM +
-</​code>​ +
- +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-ls /var/lib > /​tmp/​myname_tmpls.$$ +
-        while read f; do +
-echo $f +
-done < /​tmp/​myname_tmpls.$$ +
-rm -f /​tmp/​myname_tmpls.$$ +
-</​code>​  +
- +
- +
-<color #​22b14c>​Хорошо объявили и сразу используем много раз:</​color>​ +
-<code bash> +
-$tmpls=/​tmp/​${binname}_tmpls.$$ или $tmpls=/​tmp/​${binname}_tmpls.$$.$(RANDOM) или $tmpls=$( mktemp /​tmp/​${binname}_tmpls.$$.XXXX ) +
-ls /var/lib > $tmpls +
-while read f; do +
-        echo $f +
-done < $tmpls +
-echo ls /var/lib2 >  $tmpls +
-cat lilo.conf >  $tmpls +
-if grep ttt $tmpls; then +
-       echo ddd +
-fi +
-rm -f $tmpls +
-</​code>​ +
-</​hidden>​ +
-===== strongbash011 ===== +
-**Максимальный indent вложенность 5**\\ +
-<hidden Почему...>​ +
-Большая вложенность всегда приводит к большой вложенности мысли при чтении кода, это неудобно и приводит к ошибкам.\\ +
-Используйте ранний return или сделайте подфункции,​ или case и тп.\\ +
-Не используйте большие if then else и мозг будет занят 5-ю уровнями вложенности.\\ +
-</​hidden>​ +
- +
- +
-===== strongbash012 ===== +
-**Команды | и || и && при переносе длинных строк** \\ +
-**требуется вынести на следующую строку и поставить tab.** +
-<hidden Почему...>​ +
-Это повышает читаемость кода и делает явным, что был перенос и это продолжение предыдущей строки. +
-</​hidden>​ +
-<hidden Пример...>​ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-cat 123 | grep 123 | sed | cat | grep \ +
-        | while read t; do echo 123; done \ +
-</​code>​ +
-</​hidden>​ +
- +
-===== strongbash013 ===== +
-**Ставьте пробел после #**\\ +
-**Можно используйте без пробелов #}  и  #{ для исправления ошибок crab_indent.** +
- +
-===== strongbash014 ===== +
-**Максимальный размер функции 64 строки,​ а лучше 32.** +
-<hidden Почему...>​ +
-Каждая функция это смысловая единица которая должна помещаться в пару предложений человеческого языка, это правильное нативное удобное для мозга деления на смыслы.\\ +
-</​hidden>​ +
-<hidden Что делать если больше...>​ +
-Выделите подфункции,​ часто вида: +
-<code bash> +
-__fname(){ +
-+
-</​code>​ +
-При этом не нужно создавать миллиард функций на каждое словосочетание тк любая функция эта новая сущность,​ а плодить сущности плохо.\\ +
-И если функция из 4 строк вызывается один раз, то врядли она нужна.\\ +
-</​hidden>​ +
- +
-===== strongbash015 ===== +
-**Слишком большой линейный файл больше 64 строк, выделите подфункции.** +
-<hidden Почему...>​ +
-Если в файле больше 64 строк, значит однозначно есть команды которые делают похожие вещи и правильней их объединить в функции.\\ +
-</​hidden>​ +
-===== strongbash016 ===== +
- +
-**Уберите конечные space, tab.**\\ +
-**В конце файла должен стоять один enter.**\\ +
- +
-===== strongbash017 ===== +
- +
-**Длина строки должна быть не более 100 символов. Используйте переносы '​\'​** +
-<hidden Почему...>​ +
-Человеческий мозг нормально воспринимает до 7-10 слов в одну ширину строки,​ если больше,​ то нужно делать перенос и желательно в точке новой подкоманды.\\ +
-Не нужно надеяться на встроенные псевдопереносы IDE средств,​ это совсем другое.\\ +
-</​hidden>​ +
-<hidden Пример...>​ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-echo "​aaaaaaaaaaaaaaaaaaaaaa"​\ +
-    "​bbbbbbbbbbbbbbbbbbb"​ +
-или +
-txt="​aaaaaaaaaaaaaaaaaaaaaa"​\ +
-"​bbbbbbbbbbbbbbbbbbb"​ +
-или ​  +
-echo "​aaaaaaaaaaaaaaaaaaaaaa\ +
-bbbbbbbbbbbbbbbbbbb"​ +
- +
-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>​ +
-</​hidden>​ +
-===== strongbash018 ===== +
- +
-**Поставьте пробел перед символом перенаправления '>'​** +
-<hidden Пример...>​ +
-<code bash> +
-echo "​text"​ > file.txt +
-</​code>​ +
-</​hidden>​ +
- +
-===== strongbash019 ===== +
-**Добавьте описание и пример использования программы echo 'Info: Usage: Example: myname src dst'​** +
-<hidden Пример...>​ +
-<color #​22b14c>​Хорошо:</​color>​ +
-<code bash> +
-if [ "​${1:​---help}"​ = '​--help'​ ]; then  +
-        echo 'Info: Автоматически создавать и коммитить все файлы в каталоге'​ +
-        echo '​Usage:​ auto_git.sh [install] /​var/​www/​html'​ +
-        echo '​Example:​ auto_git.sh /​var/​www/​html'​ +
-        exit 0 +
-fi +
-</​code>​ +
-<color #​22b14c>​Хорошо при include ::​carbon.sys</​color>​ +
-<code bash> +
-sys::usage "​$@"​ и  +
-### --help Info: Автоматически создавать и коммитить все файлы в каталоге +
-### --help Usage: auto_git.sh [install] /​var/​www/​html +
-### --help Example: auto_git.sh /​var/​www/​html +
-sys::​arg_parse "​$@"​ +
-</​code>​ +
-</​hidden>​ +
-===== strongbash020 ===== +
-**Запрещены функции Log в утилитах**\\ +
-Запрещены любые LOG $(date) в утилитах,​ это можно только в демонах и в кроне +
-<code bash> +
-crab_logger {name_tool} &>>/​var/​log/​name_tool.log +
-crab_exec -t timeout --daemon --log2 -u root --onlyonce --lock {name_tool} &>>/​var/​log/​name_tool.log +
-# не утверждено как именно +
-</​code>​ +
- +
-===== strongbash021 ===== +
-**1. Запрещено удалять tmp в trap EXIT.**\\ +
-**2. Не рекомендуется использовать trap EXIT.**\\ +
-<hidden Почему...>​ +
-1. Создание временного файла это своего рода with file и его удаление это end with, чтоб было понтяно где он более не нужен аля область работы с файлом. И если файл остался в тмп, то это признак что есть ошибка в логике. +
- +
-2. Использование trap EXIT  тк он скрывает ошибки программ и никто о них не узнает,​ ломает честную логику алгоритма,​ это вредный хак. Должен быть явный вызов error_exit() и тп. +
-Если нужно удалить lock можно использовать trap TERM INT HUP, если lock остался после сбоя значит он и должен остаться,​ чтобы получить ошибки и разобраться со сбоем.\\ +
-</​hidden>​  +
-===== strongbash022 ===== +
-**1. Утилиты должны удалять за собой временные файлы**\\ +
-**2. Запрещено в утилитах передавать результаты через промежуточные файлы. Только errno stdout stderr.** +
-** В исключительных случаях имя файла должно быть в argv или конфиг в argv.**\\ +
-Непонятно как проверять,​ что результаты идут через промежуточные файлы, пока проверяем,​ что чистится /tmp/\\ +
- +
-===== strongbash023 ===== +
-**1. Нужно всегда использовать read <color #​ed1c24>​-r</​color>​ f1 f2 **\\ +
-**2. А для чтения целой строки while <color #​ed1c24>​IFS=<​nowiki>''</​nowiki></​color>​ read -r line; do**\\ +
-<hidden Почему...>​ +
-1. read -r иначе все esc последовательности обработаются,​ это вряд ли Вы хотели.\\ +
-2. IFS=<​nowiki>''</​nowiki>​ иначе начальные пробелы и табы потеряются и строка будет не та, что в оригинале.\\ +
-</​hidden>​ +
-<hidden Пример...>​ +
-<color #​ed1c24>​Как не надо делать:</​color>​ +
-<code bash> +
-read f1 f2 < /​tmp/​myfile +
- +
-while read line; do +
-        echo "​$f"​ +
-done < /​tmp/​myfile +
-</​code>​ +
-<color #​22b14c>​Как надо делать:</​color>​ +
-<code bash> +
-read -r f1 f2 < /​tmp/​myfile +
-while IFS=''​ read -r line; do +
-        echo "​$f"​ +
-done < /​tmp/​myfile +
-</​code>​ +
-</​hidden>​ +
- +
-===== strongbash024 ===== +
-** 1. Запрещено rm -rf "/​$dir"​ "​./​$dir"​ "​$dir*"​ "​$dir/​*"​ "​$dir/"​ **\\ +
-** 2. rm -rf  всегда с –one-file-system**\\  +
- +
-<hidden Почему...>​ +
-1. Это приводит к удалению незадуманных файлов если переменная пустая\\ +
-2. При работе с контейнерами и виртуалками,​ очень велик риск удалить их rootfs, а используются они сейчас повсеместно.\\ +
-</​hidden>​ +
-<hidden Пример...>​ +
-<color #​ed1c24>​Как не надо делать:</​color>​ +
-<code bash> +
-rm -rf "/​$dir"​ +
-rm -rf "​./​$dir"​ +
-rm -rf "​$dir*"​ +
-rm -rf "​$dir/​*"​ +
-rm -rf "​$dir/"​  +
-</​code>​ +
-<color #​22b14c>​Как надо делать:</​color>​ +
-<code bash> +
-rm -rf -one-file-system "​$dir"​ +
-rm -rf -one-file-system "/​var/​cache/​mydir/​*"​ +
-</​code>​ +
-</​hidden>​ +
-===== strongbash025 ===== +
-**"​do"​ и "​then"​ НЕ делаем c новой строки**\\ +
-<hidden Почему...>​В большинстве языков принято в одной строке поэтому большинству так привычней.\\ +
-</​hidden>​ +
-<hidden Пример...>​ +
-<color #​ed1c24>​Как не надо делать:</​color>​ +
-<code bash> +
-if true; +
-then +
-        echo true +
-fi +
-while read t; +
-do +
-        echo $t +
-done +
-</​code>​ +
-<color #​22b14c>​Как надо делать:</​color>​ +
-<code bash> +
-if true; then +
-        echo true +
-fi +
-while read t; do +
-        echo $t +
-done +
-</​code>​ +
-</​hidden>​ +
-===== strongbash026 ===== +
-**Нельзя использовать голые скобки для assert и тп [ a = b ]**\\ +
- +
-<hidden Почему...>​Это противоречит явности кода и человекочитаемости ошибок.\\ +
-Это использование set -e для основной логики,​ что запрещено.\\ +
-</​hidden>​\\ +
-<hidden Пример...>​ +
-<color #​ed1c24>​Как не надо делать:</​color>​ +
-<code bash> +
-[ "​$fname"​ = ""​ ] +
-</​code>​ +
-<color #​22b14c>​Как надо делать:</​color>​ +
-<code bash> +
-[ "​$fname"​ = ""​ ] && { echo '​Укажите имя файла';​ exit 1; } +
-</​code>​ +
-<color #​22b14c>​Как надо делать:</​color>​ +
-<code bash> +
-# Или не проверять все подряд,​ тк все на свете проверить анрил, само упадет по set -e +
-</​code>​ +
-</​hidden>​ +
-===== strongbash027 ===== +
-нельзя использовать конструкции вида [ a = b ] || cmd1 и cmd1 || cmd2 кроме утвержденного сахара\\ +
-используйте:​ +
-<code bash> +
-[ a != b ] && cmd1 и  +
-if ! cmd1; then +
-        cmd2 +
-fi +
-</​code>​ +
-===== strongbash028 ===== +
-**Нельзя использовать cmd1 || cmd2 || cmd3** ​ лучше проверять окружение и вызвать сразу нужное If centos if ubintu if dir \\ +
-**Пример такой сахар разрешен,​ как разрешать отдельные ошибки команд не заглушая остальные**\\ +
-<code bash> +
-Если бы не существовало команды git status +
-error=$( git commit -m '​qqqqqqqqqqq'​ 2>&1 ) \ +
-        || echo "​$error"​ | grep -qm1 '​nothing to commit'​ \ +
-        || { echo  "​$error";​ exit 1; } +
-или +
-error=$( git commit -m '​qqqqqqqqqqq'​ 2>&1 ) \ +
-        || [[ $error != *"​nothing to commit"​* ]] && { echo  "​$error";​ exit 1; } +
-</​code>​ +
-**НО правильнее** +
-<code bash> +
-if ! git status | grep -qm1 '​nothing to commit';​ then +
-       git commit -m '​qqqqqqqqqqq'​ +
-fi +
-</​code>​ +
- +
-===== strongbash029 ===== +
- +
-**Если мы берем stdout от функции мы обязаны прописать в первой строке set -e тк он снимается** +
-===== strongbash030 ===== +
-**Нельзя вызывать функцию внутри if fname и fname&&​ и fname||** +
- +
-===== strongbash031 todo ===== +
-**1. все локальные переменные должны быть объявлены через local и быть малыми буквами\\ +
-2. все глобальные переменные используемые внутри функций должны быть большими буквами +
-** +
- +
-===== TODO добавить в инструкцию как программировать на баше ===== +
-**TODO** Описать виды функций __funct funct и виды переменных ARG CONF GLOBAL local и namespace сабшелы\\ +
-**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 может уронить левую часть если это долгая команда и отгрепается первая строка пример +
-<code bash> +
- ( set -euEo pipefail; for((i=0;​i<​10;​i++));​ do echo q; sleep 1; done | grep  -q q ); echo $? +
-</​code>​ +
- +
-Добавить в описание +
-для всего есть подходящие инструменты,​ bash отличный скриптовый язык, позволяющий делать мощные программы написав немного кода по вызову готовых утилит. +
-И при этом этот код легко сопровождать и разбирать потом без программиста,​ админам и саппорту. +
-Есть куча кейсов где программы на баше в 10 раз меньше,​ чем на питоне при этом надежней и написана за гораздо меньшее время. +
- +
-~~DISCUSSION~~+