Инструменты пользователя

Инструменты сайта


linux:overall:bash:scripts

Различия

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

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

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
linux:overall:bash:scripts [2022/08/14 07:46]
admin
— (текущий)
Строка 1: Строка 1:
-====== Скриптинг ====== 
- 
-Первой строкой указывается т.н. **shebang (#!)** - последовательность двух символов, далее указывается путь к исполняющему файлу под-оболочки, так же, в этой строке можно передавать аргументы.\\ 
-Если оболочка не указана явно, используется так же, что и запускает данный скрипт.\\ 
- 
-Для исполнения скрипта, у файла должно быть разрешение выполнения (**+x**), но если передать скрипт аргументом команде **bash ./script**, тогда бит необязателен.\\ 
-Если путь к скрипту указан в **$PATH** (например **/usr/local/bin/** либо **/bin/**), то запускать можно просто по имени, без "**./**".\\ 
- 
-**Комментарии** предваряются символом решетки (**#**).\\ 
-**exit** - сообщает результат **(0-успех)** работы родительскому процессу, при отсутствии используется результат последней команды.\\ 
- 
- 
- 
-===== Аргументы (доступ к ним) ===== 
-  * **$?** - код возврата последнего процесса (функции или скрипта). 
-  * **$№** - аргументы, по номеру. &0 - последний запущенный скрипт. 
-  * **$#** - кол-во переданных аргументов. 
-  * **$*** - все аргументы одной строкой. 
-  * **$@** - все аргументы отдельной строкой. 
-  * **$-** - список флагов, переданных скрипту. 
-  * **shift** - команда, после нее первый аргумент в $@ теряется, остальные сдвигаются влево. 
- 
- 
-===== Переменные ===== 
-**Пробелы не используются при определении**\\ 
-Знак доллара используется только **при чтении** значения, работа с переменной без этого знака.\\ 
-В фигурных скобках более строгая форма (${variable}).\\ 
-**Двойные кавычки** - "нестрогие", и не влияют на механизм подстановки, в отличии от **одинарных кавычек**.\\ 
-Конкатенация строк происходит без дополнительных символов: **$Val1"_"$Val2**. 
- 
- 
-==== Встроенные переменные ==== 
-  * **$BASH** - путь к исполняемому файлу bash. 
-  * **$GROUPS** - группы пользователя. 
-  * **$HOME ** - домашний каталог. 
-  * **$HOSTNAME ** - сетевое имя хоста. 
-  * **$SHLVL ** - уровень вложенности shell. 
-  * **$SECONDS** - время работы скрипта. 
-  * **$REPLY** - для ввода read, по умолчанию. 
- 
- 
-===== Условный оператор ===== 
- 
-**Двойные квадратные скобки** работают в целом так же, как и [одинарные квадратные скобки], но имеют дополнительные возможности вроде лучшей поддержки регулярных выражений.\\ 
-**Двойные круглые скобки** это конструкция, позволяющая осуществлять арифметические вычисления внутри Bash.\\ 
-<code bash>  
-if [[ "$name" == "Ryan" ]] && ! [[ "$time" -lt 2000 ]]; then 
-  ... 
-elif [[ "$day" == "New Year's Eve" ]] || [[ "$coffee_intake" -gt 9000 ]]; then 
-  ... 
-else 
-  ... 
-fi 
- 
-if [ "$age" -gt 30 ]; then 
-  echo "What an oldy." 
-fi 
-</code> 
- 
-<code bash>  
-(( count++ )) 
-echo "$count" 
- 
-if (( -57 + 30 + 27 )); then 
-  echo "First one" 
-   
-echo $(( (5 > 3) + (0 == 0) )) 
-</code> 
- 
- 
-В условии можно использовать **код завершения любой команды**\\ 
-<code bash> 
-if grep -q coffee dialogue.txt; then .. fount/not found; fi 
- 
-if cmp a b &> /dev/null; then ... fi 
-</code> 
- 
- 
-<details> 
-<summary> :!: </summary> 
-<code bash> </code> 
-</details> 
- 
- 
- 
- 
-<details> 
-<summary> :!: Old </summary> 
-Проверяет, является ли результат **0 (истина)**.\\ 
-Условие условие проверяется с помощью команды [[main:linux:bash:утилита_test|test]], на данный момент, команда **является встроенной** т.е. не вызывает аналогичную утилиту.\\ 
-Условия можно указать следующими способами: 
-  * **if test -z $1** 
-  * **if /usr/bin/test -z $1** 
-  * **if [ -z $1 ]** 
-  * **if /usr/bin/[ -z $1** 
-  * **if [[ -z $1 ]']** - расширенный вариант простых скобок. Внутри допустимы операторы && || < и >. 
-  * **[ -z $1 ]** - условие может быть проверено из без оператора **if** 
-  * **() или двойные** - выполняет арифметическое действие внутри. **Код возврата противоположен []** 
- 
-Условный оператор проверяет код завершения **любой команды**, а не только результат выражения скобок. 
-<code bash>if cmp a b 
-then echo "Файлы идентичны" 
-else echo "Файлы различаются" 
-fi</code> 
- 
-Оператор **if** можно и не использовать. 
-<code bash>[ -z $1 ] && echo result false 
-или 
-ping -c 1 8.8.8.8 &>/dev/null || echo not available 
-</code> 
- 
- 
-==== Else if (elif) ==== 
-**elif** - краткая форма записи конструкции **else if**. 
-<code bash>if [ expr ]; then 
-  action 
-elif [ expr ]; then 
-  action 
-else 
-  action 
-fi 
-</code> 
-</details> 
- 
- 
- 
- 
-===== Циклы ===== 
-==== for ==== 
-Обработка диапазонных значений.\\ 
-**for** условие **do** действие **done**. 
-<code bash> for (( i=100; i>1; 1-- )); do action; done </code> 
- 
-Внутри **((..)')** вычисляется арифметическое выражение и возвращается результат и позволяет работать с переменными в стиле С.\\ 
- 
-Так же, можно указать диапазон: 
-<code bash>for i in {100..104}; do action; done </code> 
-<code bash>for i in 100 101 102 103 104; do action; done </code> 
-<code bash>for i in $@; do action; done </code> 
-<code bash>numbers="1 2 3 4 5" 
-for i in `echo $numbers`; do action; done </code> 
- 
- 
- 
-==== while ==== 
-Выполняется пока условие истинно.\\ 
-**while** условие **do** действие **done**. 
-<code bash>while [ $v1 -le $v2 ] do <action> done</code> 
-В двойных скобках символ **$** перед переменной можно опустить, так же, двойные скобки позволяют наращивать значение переменной **( (v+=1) )** 
-<code bash>while (( v1 <= v2 )') ; do action; done </code> 
- 
-<details> 
-<summary> :!: Примеры </summary> 
-Бесконечный цикл 
-<code bash> 
-while true 
-do 
-        echo "--==" $(uname -a) "==--" 
-        sleep 2 
-done 
-</code> 
- 
- 
-</details> 
- 
- 
- 
-==== Until ==== 
-Противоположно циклу **while**, выполняется пока условие ложно. 
-**until** условие **do** действие **done**. 
-Все остальное аналогично. 
- 
- 
- 
-===== case ===== 
-<code bash>case $v1 in 
-val1) 
-  action1;; 
-val2) 
-  action2;; 
-*) 
-  default action;; 
-esac 
-</code> 
- 
- 
- 
-===== Работа со строками ===== 
-**Длина строки:** 
-<code bash>echo ${#string} 
-echo `expr length $string` 
-</code> 
- 
-**Извлечение подстроки** 
-<code bash>${string:position} # вместо $string можно поставить * или @ 
-${string:position:length} 
-expr substr $string $position $length 
-</code> 
- 
-**Удаление части строки** 
-<code bash>${string#(##)substring} # Удаляет самую короткую (длинную), ищет с начала строки 
-${string%(%%)substring} # Удаляет самую короткую (длинную), ищет с конца строки 
-</code> 
- 
-**Замена подстроки** 
-<code bash>${string/substring/replacement} // Первое вхождение 
-${string//substring/replacement} // Все вхождения 
-</code> 
- 
- 
- 
-===== Отладка ===== 
-Для отладки, можно использовать команду **bash -x файл_скрипта**. 
- 
- 
-===== Примеры ===== 
-**"Около-многопоточность"**\\ 
-Используется минимум два скрипта, в первом выполнение работы, второй в цикле запускает подоболочку в фоне, не дожидаясь окончания каждого. Ньюанс в том что в конце головной скрипт не закрывается сам, думаю можно исправить аргументами. 
-<code bash> for CurrAddr in {1..25}; do 
-./oneping $CurrAddr & # Там происходит просто пинг переданного адреса 
-done 
-# В итоге, ждем тайм-аут один раз, для всех хостов 
-</code> 
- 
- 
- 
-===== Утилита test ===== 
- 
-Unix утилита для проверки типа файла и сравнения значений.\\ 
-Возвращает 0 (истина) или 1 (ложь). Выражения могут быть как унарными так и бинарными.\\ 
- 
-**Использование:** <code bash># test [expr]</code> 
-**Пример:** <code bash>if test -f file.txt или [ -f file.txt ] 
-then 
-  rm file.txt 
-else 
-  echo 'no found' 
-fi 
-</code>  
- 
- 
- 
-==== Параметры запуска ==== 
-  * **-d file** - если file существует и является директорией. 
-  * **-e file** - если file существует. 
-  * **-f file** - если file существует и является обычным файлом. 
-  * **-k file** - если file существует и ему установлен "sticky" бит. 
-  * **-L file** - если file существует и является символьной ссылкой. 
-  * **-r (-w/-x) file** - если file существует и читаем (записываем/исполняем). 
-  * **-z str** - если длина 0. 
-  * **-n str** - если длина не 0. 
-  * **-a (-o)** - аналог && (||) в одинарных скобках. 
-  * **str1 = ('!=') str2** - если строки равны (не равны). 
- 
- 
-===== Функции. Возврат значения ===== 
- 
-**function_name() {command... }**\\ 
-Объявляются раньше вызова, **нет возможности предобъявления**\\ 
-**return** возвращает только интовое значение, до 255\\ 
- 
- 
- 
-===== Примеры ===== 
- 
-<details> 
-<summary> :!: Обширный пример </summary> 
- 
-<code bash> 
-#!/bin/bash 
- 
-# Входные параметры можно передать аргументами, тогда скрипт не будет ничего запрашивать 
-# Если что то не передано, скрипт запросит пользователя интерактивно 
- 
-isNewMultip=false 
- 
-CRed='\033[31m' 
-CGreen='\033[32m' 
-CCyan='\033[36m' 
-CNone='\033[0m' 
- 
-# Разбираем аргументы 
-while getopts :i:f:n:a: flag 
-do 
- case "${flag}" in 
- i) importName=$OPTARG;; 
- f) multipName=$OPTARG;; 
- n) multipName=$OPTARG 
- isNewMultip=true;; 
- a) hostIP=$OPTARG;; 
- *) printf "$0 [OPTIONS]\n  -i Имя нового импорта\n  -f Имя существующего файлмультипликатора\n  -n Имя нового файлмультипликатора\n -a IP адрес хоста\n" 
- exit;; 
-    esac 
-done 
- 
-importName=$(sed 's/[\*|\/|\$|\@|\.| ]/_/g' <<< ${importName}) 
-multipName=$(sed 's/[\*|\/|\$|\@|\.| ]/_/g' <<< ${multipName}) 
-hostIP=$(grep -Po "([0-9]{1,3}\.){3}[0-9]{1,3}" <<< ${hostIP}) 
- 
- 
-# -= Если не передано в аргументах или некорректно, запрашиваем у пользователя =- 
-if [ -z ${hostIP} ]; then 
- listIP=($( ip a | grep -Po "inet \K[^/]*" | grep -v "127.0.0.1")) 
- if [[ ${#listIP[*]} > 1 ]]; then 
- printf '  - %s\n' "${listIP[@]}" 
- while read -p "Укажите ip адрес хоста: " hostIP; do 
- hostIP=$(grep -Po "([0-9]{1,3}\.){3}[0-9]{1,3}" <<< ${hostIP}) 
- if [ -n "$hostIP" ]; then 
- break 
- fi 
- done 
- else 
- hostIP=${listIP[0]} 
- fi 
-fi 
- 
- 
-if [ -z "$importName" ]; then 
- listImports=($( cat /tank/BIN/MgaImport/app.conf | grep "WORKSPACE" | grep -Po ".*/\K.*" )) 
- echo -e "${CCyan}Существующие сервисы:${CNone}" 
- printf '  - %s\n' "${listImports[@]}" 
-  
- while read -p "Введите имя нового импорта: " importName; do 
- importName=$(sed 's/[\*|\/|\$|\@|\.| ]/_/g' <<< ${importName}) 
- if [ -n "$importName" ]; then 
- break 
- fi 
- done 
-fi 
- 
- 
-if [ -z "$multipName" ]; then 
- listMultips=($( cat /tank/BIN/FileMultiplicators/app.conf | grep "WORKSPACE" | grep -Po ".*/\K.*" )) 
- echo -e "${CCyan}Существующие файлмультипликаторы:${CNone}" 
- printf '  - %s\n' "${listMultips[@]}" 
-  
- while read -p "Введите имя файлмультипликатора: " multipName; do 
- multipName=$(sed 's/[\*|\/|\$|\@|\.| ]/_/g' <<< ${multipName}) 
- if [ -n "$multipName" ]; then 
- break 
- fi 
- done 
- 
- if [[ ! "${listMultips[*]}" =~ "${multipName}" ]]; then 
- echo -e "Указанное имя не найдено, ${CCyan}создать файлмультипликатор${CNone} ? " 
- select yn in "Yes" "No"; do 
- case $yn in 
- Yes) isNewMultip=true; break;; 
- No) echo -e "Указаный файлмультипликатор ${CRed}не существует${CNone}"; exit;; 
- esac 
- done 
- fi 
-fi 
- 
- 
-# -= Ищем свободные порты =- 
-# Мультипликатор 
-    # Команный порт 
-listPorts=($(cat /tank/BIN/FileMultiplicators/*/FileMultiplicator.toml | grep "listeningCommandPort" | grep -Po "\d*" | sort)) 
-(( listPorts[-1]++ )) 
-while $(ss -tulpn | grep -q :${listPorts[-1]}); do 
- (( listPorts[-1]++ )) 
-done 
-multipCommandPort=${listPorts[-1]} 
- 
- # Jmx порт 
-listPorts=($(cat /tank/BIN/FileMultiplicators/app.conf | grep "jmxremote.port" | grep -Po "\d*" | sort)) 
-(( listPorts[-1]++ )) 
-while $(ss -tulpn | grep -q :${listPorts[-1]}); do 
- (( listPorts[-1]++ )) 
-done 
-multipJmxPort=${listPorts[-1]} 
- 
-# Импорт 
-    # Команный порт 
-listPorts=($(cat /tank/BIN/MgaImport/app.conf | grep "COMMAND_PORT" | grep -Po "\d*" | sort)) 
-(( listPorts[-1]++ )) 
-while $(ss -tulpn | grep -q :${listPorts[-1]}); do 
- (( listPorts[-1]++ )) 
-done 
-importCommandPort=${listPorts[-1]} 
- 
-    # Jmx порт 
-listPorts=($(cat /tank/BIN/MgaImport/app.conf | grep "jmxremote.port" | grep -Po "\d*" | sort)) 
-(( listPorts[-1]++ )) 
-while $(ss -tulpn | grep -q :${listPorts[-1]}); do 
- (( listPorts[-1]++ )) 
-done 
-importJmxPort=${listPorts[-1]} 
- 
- 
-# -= Создаем импорт =- 
-$(cp -r ClearImport "/tank/BIN/MgaImport/MgaImport_${importName}") 
- 
-# Меняем права доступа юзеру mgaimport 
-$(chown -R mgaimport:mgaimport "/tank/BIN/MgaImport/MgaImport_${importName}") 
- 
-# Пишем параметры в "cmd.properties" 
-changeFile="/tank/BIN/MgaImport/MgaImport_${importName}/cmd.properties" 
-$(sed -i 's/%JmxPort%/'${importJmxPort}'/g' ${changeFile}) 
-$(sed -i 's/%CommandPort%/'${importCommandPort}'/g' ${changeFile}) 
-$(sed -i 's/%ImportName%/'${importName}'/g' ${changeFile}) 
- 
-# Пишем параметры в "./properties/mgaimport.toml" 
-changeFile="/tank/BIN/MgaImport/MgaImport_${importName}/properties/mgaimport.toml" 
-$(sed -i 's/%InputDir%/'"\/tank\/MGA_IN\/${importName}"'/g' ${changeFile}) 
-$(sed -i 's/%SepticDir%/'"\/tank_storage\/septics\/SEPTIC_${importName}"'/g' ${changeFile}) 
-$(sed -i 's/%DBErrorDir%/'"\/tank_storage\/dberrors\/DBERROR_${importName}"'/g' ${changeFile}) 
-$(sed -i 's/%CommandPort%/'${importCommandPort}'/g' ${changeFile}) 
- 
-# Делаем запись в общем конфиге 
-changeFile="/tank/BIN/MgaImport/app.conf" 
-$(printf "\n[${importName}] 
-# ---------------------------------------- # 
-  ENABLE="true" 
-  JAVA_HOME=/usr/lib/jvm/bellsoft-java14-full.x86_64/bin 
-  START_USER=mgaimport 
-  START_TIME=30 
-  STOP_TIME=90 
-  COMMAND_PORT=${importCommandPort} 
-  WORKSPACE=/tank/BIN/MgaImport/MgaImport_${importName} 
- 
-  CMD='java -XX:+UnlockExperimentalVMOptions 
-  -XX:+UseG1GC 
-  -XX:+DisableExplicitGC 
-  -Xmx16G 
-  -Xms3G 
-  -XX:InitiatingHeapOccupancyPercent=75 
-  -XX:G1NewSizePercent=1 
-  -XX:G1MaxNewSizePercent=15 
-  -XX:G1MixedGCLiveThresholdPercent=90 
-  -XX:G1HeapWastePercent=5 
-  -XX:G1ReservePercent=1 
-  -XX:+ExplicitGCInvokesConcurrent 
-  -XX:+HeapDumpOnOutOfMemoryError 
-  -XX:HeapDumpPath="/tank/BIN/MgaImport/MgaImport_${importName}/out_of_memory_dump/dump.hprof" 
-  -XX:-OmitStackTraceInFastThrow 
-  -Dcom.sun.management.jmxremote 
-  -Dcom.sun.management.jmxremote.port=${importJmxPort} 
-  -Dcom.sun.management.jmxremote.authenticate=false 
-  -Dcom.sun.management.jmxremote.ssl=false 
-  -Djava.rmi.server.hostname=${hostIP} 
-  -Djava.net.preferIPv4Stack=true 
-  -jar mgaimport.jar'\n" >> ${changeFile}) 
- 
- 
-if [ $isNewMultip ]; then  
- # -= Создаем мультипликатор =- 
- $(cp -r ClearFileMultiplicator "/tank/BIN/FileMultiplicators/${multipName}") 
- 
- # Меняем права доступа юзеру mgaimport 
- $(chown -R mgaimport:mgaimport "/tank/BIN/FileMultiplicators/${multipName}") 
- 
- # Пишем параметры 
- changeFile="/tank/BIN/FileMultiplicators/${multipName}/FileMultiplicator.toml" 
- $(sed -i 's/%InputDir%/'"\/tank\/IN\/${multipName}"'/g' ${changeFile}) 
- $(sed -i 's/%CommandPort%/'${multipCommandPort}'/g' ${changeFile}) 
- $(sed -i 's/%ImportName%/'${importName}'/g' ${changeFile}) 
- $(sed -i 's/%ImportPath%/'"\/tank\/MGA_IN\/in_${importName}"'/g' ${changeFile}) 
- 
- 
- # Делаем запись в общем конфиге 
- changeFile="/tank/BIN/FileMultiplicators/app.conf" 
- $(printf "\n[${multipName}] 
-# ----------------------------------- # 
-  ENABLE="true" 
-  JAVA_HOME=/usr/lib/jvm/bellsoft-java14-full.x86_64/bin 
-  START_USER=mgaimport 
-  START_TIME=5 
-  STOP_TIME=10 
-  WORKSPACE=/tank/BIN/FileMultiplicators/${multipName} 
- 
-  CMD='java 
-  -XX:+UnlockExperimentalVMOptions 
-  -XX:+UseG1GC 
-  -XX:+DisableExplicitGC 
-  -Xmx2G 
-  -Dcom.sun.management.jmxremote 
-  -Dcom.sun.management.jmxremote.port=${multipJmxPort} 
-  -Dcom.sun.management.jmxremote.authenticate=false 
-  -Dcom.sun.management.jmxremote.ssl=false 
-  -Djava.rmi.server.hostname=${hostIP} 
-  -Djava.net.preferIPv4Stack=true 
-  -jar filemultiplicator-all.jar'\n" >> ${changeFile}) 
- 
- # Создаем входящую директорию мультипа 
- $(install -d -m 775 -o mgaimport -g mgaimport "/tank/IN/${multipName}") 
- 
- # Запись в самбу 
- changeFile="/etc/samba/smb.conf" 
- $(printf "\n[${multipName}] 
-path = /tank/IN/${multipName} 
-guest ok = no 
-browsable = no 
-writeable = yes 
-create mask = 0770 
-directory mask = 0770 
-write list = xlogssupplier 
-valid users = xlogssupplier 
-force user = mgaimport 
-force group = mgaimport\n" >> ${changeFile}) 
- 
- # Перезапускаем самбу 
- $(systemctl restart smb && systemctl status smb) 
- 
- # Напоминаем пользователю что нужно примонтировать ее на источнике источника 
- printf "${CRed}Внимание!${CNone} 
-Создана входящая папка для файлмультипликатора ${CCyan} \"/tank/IN/${multipName}\" ${CNone} 
-К ней ${CRed}открыт сетевой доступ${CNone} через \"smb\", ее необходимо примонтировать на сервере \"лог-дистрибьютора\" (либо какой то другой источник) для получения входящих логов\n" 
- 
-else 
- # -= Используем существующий =- 
- # Дозапись в конфиг еще новый сервис 
- changeFile="/tank/BIN/FileMultiplicators/${multipName}/FileMultiplicator.toml" 
- $(printf "\n[[DestDir]] 
-        name = \"${importName}\" 
-        destDir = \"/tank/MGA_IN/in_${importName}\" 
-        pattern = \"^.*$\"\n" >> ${changeFile}) 
-  
- # Перезапуск сервиса, для принятия изменений 
-    $("/tank/BIN/FileMultiplicators/${multipName}/restart.sh") 
- $("/tank/BIN/FileMultiplicators/${multipName}/status.sh") 
-fi 
- 
- 
-# -= Создаем входящую папку импорта и папки для ошибок =- 
-$(install -d -m 775 -o mgaimport -g mgaimport "/tank/MGA_IN/IN_${importName}") 
-$(install -d -m 775 -o mgaimport -g mgaimport "/tank_storage/dberrors/DBERROR_${importName}") 
-$(install -d -m 775 -o mgaimport -g mgaimport "/tank_storage/septics/SEPTIC_${importName}") 
- 
- 
-printf "\n${CGreen}Новый импорт успешно создан!${CNone} 
-Параметры следующие: 
-    Имя: ${CCyan}${importName}${CNone} 
-    Расположение: ${CCyan}'/tank/BIN/MgaImport/MgaImport_${importName}'${CNone} 
-    Входящая директория: ${CCyan}'/tank/MGA_IN/IN_${importName}'${CNone} 
-    Jmx-порт: ${CCyan}${importJmxPort}${CNone} 
-    Командный порт: ${CCyan}${importCommandPort}${CNone} 
-    Конфигурация импорта: ${CCyan}'/tank/BIN/MgaImport/MgaImport_${importName}/properties/mgaimport.toml'${CNone} 
-    Общая конфигурация всех импортов: ${CCyan}'/tank/BIN/MgaImport/app.conf'${CNone} 
-    Файл мультипликатор: ${CCyan}'/tank/BIN/FileMultiplicators/${multipName}${CNone} 
- 
-Укажите ${CCyan}параметры импорта в БД${CNone} в файле конфигурации импорта 
-Используя Jmx-порт, создайте самостоятельно мониторинг в Zabbix, при необходимости\n" 
-</code> 
-</details> 
- 
- 
- 
- 
  
linux/overall/bash/scripts.1660463195.txt.gz · Последнее изменение: 2022/08/14 07:46 — admin