Авторизоваться
Аким Солянкин 29.05.2021 Опубликована

8 советов по сценариям Bash для проектов автоматизации 

Используя сценарий Bash, я автоматизировал Backpack для модулей Laravel для установки / удаления. В этом проекте я выбрал восемь практических советов, которые можно применить к любому проекту сценариев Bash.

Скрипт Backpack_install Bash в действии.
Скрипт Backpack_install Bash в действии.

Исходная информация

Laravel - самый популярный фреймворк PHP. Backpack for Laravel - это набор пакетов Laravel, которые помогают создавать пользовательские панели администрирования. Он имеет восемь модулей, включая ядро, диспетчер разрешений, диспетчер страниц, меню и диспетчер файлов.

Вот мой репозиторий backpack_install на Github.

Требования

Вам необходимо знать основы сценариев Bash и иметь некоторый опыт написания базовых сценариев Bash.

1. Задайте переменные и аргументы перед функциями.

Shellman - это не только расширение фрагмента сценария оболочки для VS Code, но и бесплатная электронная книга с многочисленными полезными фрагментами и советами по созданию сценариев на Bash.

Книга предлагает следующую структуру.

1. shebang
2. summary
3. handler functions
4. event handers
5. functions
6. argument parsing
7. setting default variable values
8. rest of code (main body)

Часто вам нужно объявить переменные и функции перед их использованием. Я придумываю структуру, которая мне подходит. Анализ аргументов и установка значений переменных по умолчанию после того, как функции не были опциями.

Вот структура, к которой я пришел:

1. shebang
2. summary
3. default variable values
4. arguments parsing (including usage function which uses variables from 3.)
5. importing files (otherwise the file becomes too long.)
6. functions (using variables and functions from 3, 4 & 5.)
7. event functions (Ctrl+C event using a function from 5 & 6.)
8. check-command function (checking if the system has commands.)
9. read standard input
10. main body (using functions from 5 & 6.)

Я объявляю значения переменных по умолчанию, аргументы синтаксического анализа и файлы импорта перед функциями, чтобы я мог использовать переменные для параметров функции.

2. Получение / импорт файлов

Скрипту необходимо установить восемь модулей, поэтому я разделил каждую установку на отдельные файлы.

Я мог бы использовать source ./lib/file_name или . ./lib/file_name для импорта файлов в основной скрипт, но Shellman предоставляет альтернативнуюфункцию import.

Я создал каталог lib и сохранил в нем все файлы, которые нужно импортировать. Добавьте функцию импорта Shellman’s в основной скрипт:

Использование функции импорта Шеллмана.
function import() {
    local file="./lib/${1}"
    if [ -f "${file}" ]; then
        # shellcheck disable=SC1090
        source "${file}"
    else
        echo "Error: Cannot find library at: ${file}"
        exit 1
    fi
}

# Usage: import "filename"
import "banners"
import "bp_crud"
# More lines ...

Строка 2: вы можете добавить .sh после, ${1} если у вашего файла есть расширение.

Строка 0: Вам не нужно добавлять файлы #!/usr/bin/env bash в начало или делать файлы исполняемыми. Если вы это сделаете, заставьте текстовый редактор использовать форматирование и подсветку синтаксиса.

Использование источника

Файлы в каталоге lib должны иметь функцию (и), если вы хотите использовать аргументы функции. Например, функции в файле lib/banners используют три параметра.

#!/usr/bin/env bash

# lib/banners
# Usage: bannerSimple "my title" "*"
function bannerSimple() {
    local msg="${2} ${1} ${2}"
    local edge=$(echo "${msg}" | sed "s/./"${2}"/g")
    echo "${edge}"
    echo "$(tput bold)${msg}$(tput sgr0)"
    echo "${edge}"
    echo
}

# Usage: bannerColor "my title" "red" "*"
function bannerColor() {
    case ${2} in
    black)
        color=0
        ;;
    red)
        color=1
        ;;
    green)
        color=2
        ;;
    yellow)
        color=3
        ;;
    blue)
        color=4
        ;;
    magenta)
        color=5
        ;;
    cyan)
        color=6
        ;;
    white)
        color=7
        ;;
    *)
        echo "color is not set"
        exit 1
        ;;
    esac

    local msg="${3} ${1} ${3}"
    local edge=$(echo "${msg}" | sed "s/./${3}/g")
    tput setaf ${color}
    tput bold
    echo "${edge}"
    echo "${msg}"
    echo "${edge}"
    tput sgr 0
    echo
}

Файл lib/bp_pagemanager использует команду source для чтения файла и одну из функций:

#!/usr/bin/env bash
# file name: lib/pagemanager

# shellcheck disable=SC1091
source ./lib/banners

fn_pagemanager() {

    laravel_dir=$1
    script_dir=$2
    cd "${laravel_dir}" || exit 1

    echo
    bannerColor "PAGEMANAGER: Installing PageManager." "blue" "*"
    echo
    bannerColor 'PAGEMANAGER: Adding app/PageTemplates.php' "blue" "*"
    pagetemp=./app/PageTemplates.php
    if [[ ! -e $pagetemp ]]; then
        cp "$script_dir"/bp_files/PageTemplates.php "$laravel_dir"/app
    fi
    echo
    bannerColor 'PAGEMANAGER: Running composer require backpack/pagemanager' "blue" "*"
    composer require backpack/pagemanager || exit 4
    echo
    bannerColor 'PAGEMANAGER: Running php artisan vendor:publish --provider' "blue" "*"
    php artisan vendor:publish --provider="Backpack\PageManager\PageManagerServiceProvider" || exit 4
    echo
    bannerColor 'PAGEMANAGER: Running php artisan migrate' "blue" "*"
    php artisan migrate || exit 4
    echo
    bannerColor 'PAGEMANAGER: Running php artisan backpack:add-sidebar-content' "blue" "*"
    php artisan backpack:add-sidebar-content "<li class='nav-item'><a class='nav-link' href='{{ backpack_url('page') }}'><i class='nav-icon la la-file-o'></i> <span>Pages</span></a></li>" || exit 4
    echo
    bannerColor 'PAGEMANAGER: PageManager installed' "blue" "*"
}

Строка 5: получение файла баннеров.

Строка 14: Использование функции bannerColor с тремя аргументами.

3. Использование баннера

Баннер - это полезный способ рассказать пользователям, что делает ваш скрипт. Если вы используете обычный текст, пользователи этого не заметят.

Импортируйте файл и используйте функцию bannerColor, как в следующих примерах.

Для этого требуются три параметра: содержимое баннера, цвет и символ.

Примеры :

'Installing CRUD.' "blue" "*"
Результат работы bannerColor ‘Installing CRUD.’ “blue” “*”
Результат работы bannerColor ‘Installing CRUD.’ “blue” “*”
bannerColor "Happy Coding!" "magenta" "*"
Результат работы bannerColor “Happy Coding!” “magenta” “*”
Результат работы bannerColor “Happy Coding!” “magenta” “*”
bannerColor "Uninstalling ..." "red" "*"
Результат работы bannerColor “Happy Coding!” “magenta” “*”
Результат работы bannerColor “Happy Coding!” “magenta” “*”
bannerColor 'Running php artisan optimize:clear' "yellow" "*"T
Результат работы bannerColor ‘Running php artisan optimize:clear’ “yellow” “*
Результат работы bannerColor ‘Running php artisan optimize:clear’ “yellow” “*

Выберите цвет из черного, красного, зеленого, желтого, синего, пурпурного, голубого и белого.

Используйте любой символ (ы) , как ***>>^^^.

4. Обработчик событий, использующий ловушку для завершения.

Когда оболочка получает сигнал, например о завершении Ctrl-C, команда  trap перехватывает сигнал и выполняет команду.

Команда trap имеет структуру trap func signal(s).

Вы можете определить func в соответствии с вашими потребностями и использовать имя(имена) сигнала, на которые реагирует функция. В нашем случае я использовал SIGINT, который предназначен для прерывания Ctrl-C.

Пример :

on_ctrl_c из сниппета Shellman.
# CTRL+C event handler
on_ctrl_c() {
    echo       # Set cursor to the next line of '^C'
    tput cnorm # show cursor. You need this if animation is used.
    echo "Terminated with Ctrl+C."
    echo "Removing backpack modules ..."
    uninstall_bp "$laravel_dir"
    exit 1 # Don't remove. Use a number (1-255) for error code.
}

# Put this line at the beginning of your script (after functions used by event handlers).
# Register CTRL+C event handler
trap on_ctrl_c SIGINT

Чтобы найти имена сигналов в Linux, запустите trap -l.

macOS использует ZSH в качестве оболочки по умолчанию, поэтому вам нужно изменить оболочку на bash. Используйте команду bash, затем trap -l или запустите chsh -s /bin/bash, чтобы изменить оболочку, откройте новую вкладку, а затем запустите trap -l:

Сигналы Ubuntu. Используйте trap -lкоманду.Изображение автора.
Сигналы Ubuntu. Используйте trap -lкоманду.Изображение автора.
сигналы macOS.Изображение автора
сигналы macOS.Изображение автора

5. Удаление

Вам нужно выполнить несколько команд composer remove для удаления пакетов, команду find --delete для удаления файлов миграции php artisan optimize:clear и dump-autoload для очистки всех кешей.

Функция удаления.
uninstall_bp() {
    laravel_dir="$1"
    cd "$laravel_dir" || exit 1
    composer remove backpack/backupmanager
    composer remove backpack/logmanager
    composer remove backpack/settings
    composer remove backpack/permissionmanager
    composer remove backpack/pagemanager
    composer remove backpack/menucrud
    composer remove backpack/newscrud
    composer remove backpack/filemanager
    bannerColor 'Removing files from database/migrations' "yellow" "*"
    find "${laravel_dir}"/database/migrations -type f ! -name '*00000*' -delete
    bannerColor 'Running php artisan optimize:clear' "yellow" "*"
    php artisan optimize:clear
    bannerColor 'Running composer dump-autoload' "yellow" "*"
    composer dump-autoload
    bannerColor "Cleaning up laravel.log" "yellow" "*"
    echo "" >"$laravel_dir"/storage/logs/laravel.log
    bannerColor "Please run the following commands for complete uninstallation." "yellow" "*"
    echo "$ cd $laravel_dir"
    if git rev-parse --git-dir >/dev/null 2>&1; then
        echo "$ git reset --hard"
        echo "$ git clean -f -d"
    fi
    echo "$ rm -rf vendor/backpack"
    bannerColor "Then clear your database." "yellow" "*"
    exit 0
}

Строка 22: Используйте, git rev-parse --git-dir чтобы определить, является ли каталог каталогом Git или нет. Если это так, используйте сброс скрипта и очистите репозиторий git.

6. Проверьте функции

Используйте функцию check_cmd, чтобы проверить, есть ли в системе пользователя необходимые команды. Сохраняю функцию check_cmd в файле lib/utils.

Пример :

check_cmd функция.
check_cmd() {
    if [[ ! $(command -v "$1") ]]; then
        bannerColor "It seems like you don't have $1." "red" "*"
        bannerColor "Please install $1 or add the PATH to .zshrc or .bash_profile." "red" "*"
        exit 1
    fi
}

# check commands
check_cmd sed
check_cmd composer
check_cmd laravel

Строка 2: Используйте, $(command -v "$1") чтобы проверить, есть ли в системе пользователя требуемая команда. Если нет, выйдите с кодом выхода 1.

7. Чтение стандартного ввода

Когда вы читаете стандартный ввод пользователя, вы можете выбрать первую букву,  cut -c 1-1 и перенести ее в заглавную букву, tr "[:lower:]" "[:upper:]".

Пример :

Чтение стандартного ввода.
# Confirm if user updated the .env file especially APP_URL
read -rp "Have you updated .env file, like APP_URL, etc? yes/y or no/n   " ENV

env_ans=$(echo "$ENV" | cut -c 1-1 | tr "[:lower:]" "[:upper:]")

if [ ! "$env_ans" = Y ]; then
    bannerColor "Update your .env file." "red" "*"
    exit 1
fi

Используйте оператор if и выйдите, если введено не Y.

8. Параметры

Функция опции Шеллмана является альтернативой функции чтения. Пользователи выбирают вариант с помощью клавиш вверх / вниз. Я сохраняю функции inputChoice в файле lib/utils.

Когда вы его используете, сначала определите переменную параметров:

options=("one" "two" "three");
inputChoice "Choose:" 0 "${options[@]}";
choice=$?; 
echo "${options[$choice]}"

Первый параметр функции inputChoice - это текст, который вы хотите отобразить. Второй параметр - выбор по умолчанию. 0 выбирает первый вариант. Третий параметр требует настройки, ${options[@]}.

Пример :

# if $uninstall is true run uninstall
if [[ "$uninstall" = true ]]; then
    # confirm if you are sure
    options=("Yes" "No") # 0 or 1
    inputChoice "Uninstalling packages. Are you sure?" 0 "${options[@]}"
    choice=$?

    if [ "$choice" = 0 ]; then
        bannerColor "Uninstalling ..." "red" "*"
        uninstall_bp "$laravel_dir"
    else
        bannerColor "Try it again." "red" "*"
        exit 1
    fi
    exit 0
fi

В приведенном выше коде, если установлен флаг -u, подтвердите намерение пользователя с помощью функции параметров.

Выходные данные функции inputChoice.Изображение автора.
Выходные данные функции inputChoice.Изображение автора.

Вывод

Когда вы изучаете новые методы, рекомендую внедрять их в свои существующие проекты. Надеюсь, вы сможете использовать некоторые из этих советов в своем проекте.

Если вы повторяете строки кода, пора их автоматизировать. Скрипты на Bash - один из лучших вариантов.

Удачного кодирования

Коментарии
Авторизоваться что-бы оставить комментарий
Присоединяйся в тусовку
Наш сайт использует файлы cookie для вашего максимального удобства. Пользуясь сайтом, вы даете свое согласие с условиями пользования cookie