Первой строкой указывается т.н. shebang (#!) - последовательность двух символов, далее указывается путь к исполняющему файлу под-оболочки, так же, в этой строке можно передавать аргументы.
Если оболочка не указана явно, используется так же, что и запускает данный скрипт.
Для исполнения скрипта, у файла должно быть разрешение выполнения (+x), но если передать скрипт аргументом команде bash ./script, тогда бит необязателен.
exit - сообщает результат (0-успех) работы родительскому процессу, при отсутствии используется результат последней команды.
Пробелы не используются при определении
Знак доллара используется только при чтении значения, работа с переменной без этого знака.
В фигурных скобках более строгая форма ${variable}.
Двойные кавычки - «нестрогие», и не влияют на механизм подстановки, в отличии от одинарных кавычек.
Конкатенация строк происходит без дополнительных символов: $Val1«_»$Val2.
${переменная/шаблон/замена} - замена первого совпадения ${переменная/шаблон} - удалить первое совпадение ${переменная//шаблон/замена} - замена каждого совпадения (# в начале, % в конце переменной) ${string:position [:length] } - подстрока ${переменная:-значение} - значение по умолчанию для переменной ${переменная:=значение} - если переменной нет то присваиваем значение ${переменная:?значение} - использовать переменную если установлена, либо выйти с ошибкой (значение) ${переменная:+значение} - использовать значение если переменная установлена, иначе ничего ${переменная#шаблон} - значение переменной после удаления шаблона слева, самый короткий (## самый длинный) (% %% тоже самое только справа)
Индексные
Инициализируется перечнем значений в круглых скобах, через пробел. Работает отрицательный индекс
a=(0 1 2 3 4 5) # Первый / Четвертый / предпоследний элемент / второй ${a}; ${a[4]}; ${a[-2]}; ${a[3-1]} # Все элементы массива ${arr[*]}; ${arr[@]}; # Ряд элементов массива ${#arr[]}; ${#arr[]}; # Длина массива ${#arr[@]}
Ассоциативные
# Объявить так declare -A arr arr[index_foo]=value_foo arr[index_bar]=value_bar arr[index_xyz]=value_xyz # Либо так array_name=( [index_foo]=value_foo [index_bar]=value_bar [index_xyz]=value_xyz ) # Перебор массива должен быть таким # Обязательно с воскл знаком, иначе не те значения for key in ${!from_49[@]}; do
Двойные квадратные скобки работают в целом так же, как и [одинарные квадратные скобки], но имеют дополнительные возможности вроде лучшей поддержки регулярных выражений.
Двойные круглые скобки это конструкция, позволяющая осуществлять арифметические вычисления внутри 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
(( count++ )) echo "$count" if (( -57 + 30 + 27 )); then echo "First one" echo $(( (5 > 3) + (0 == 0) )) # В условии можно использовать **код завершения любой команды**\\ if grep -q coffee dialogue.txt; then .. fount/not found; fi if cmp a b &> /dev/null; then ... fi
Проверяет, является ли результат 0 (истина).
Условие условие проверяется с помощью команды test, на данный момент, команда является встроенной т.е. не вызывает аналогичную утилиту.
Условия можно указать следующими способами:
Условный оператор проверяет код завершения любой команды, а не только результат выражения скобок.
if cmp a b then echo "Файлы идентичны" else echo "Файлы различаются" fi
Оператор if можно и не использовать.
[ -z $1 ] && echo result false или ping -c 1 8.8.8.8 &>/dev/null || echo not available
elif - краткая форма записи конструкции else if.
if [ expr ]; then action elif [ expr ]; then action else action fi
Обработка диапазонных значений.
for условие do действие done.
for (( i=100; i>1; 1-- )); do action; done # Внутри **((..)')** вычисляется арифметическое выражение и возвращается результат и позволяет работать с переменными в стиле С. Так же, можно указать диапазон for i in {100..104}; do action; done for i in 100 101 102 103 104; do action; done for i in $@; do action; done numbers="1 2 3 4 5" for i in `echo $numbers`; do action; done # Перебор массива, выполнение команды с каждым элементом list=(user1 user2 user3 user4 user5 user6) for i in ${list[*]}; do printf '\n=======%s\n', $i influx -execute 'show grants for '$i';' -username '<auth>' -password '<auth>' done
Выполняется пока условие истинно.
while условие do действие done.
В двойных скобках символ $ перед переменной можно опустить, так же, двойные скобки позволяют наращивать значение переменной ( (v+=1) )
while [ $v1 -le $v2 ] do <action> done while (( v1 <= v2 )') ; do action; done
Бесконечный цикл
while true do echo "--==" $(uname -a) "==--" sleep 2 done
Противоположно циклу while, выполняется пока условие ложно. until условие do действие done. Все остальное аналогично.
case $v1 in val1) action1;; val2) action2;; *) default action;; esac
# Длина строки echo ${#string} echo `expr length $string`
Для отладки, можно использовать команду bash -x файл_скрипта.
«Около-многопоточность»
Используется минимум два скрипта, в первом выполнение работы, второй в цикле запускает подоболочку в фоне, не дожидаясь окончания каждого. Ньюанс в том что в конце головной скрипт не закрывается сам, думаю можно исправить аргументами.
for CurrAddr in {1..25}; do ./oneping $CurrAddr & # Там происходит просто пинг переданного адреса done # В итоге, ждем тайм-аут один раз, для всех хостов
**Записать случайные байты в файл**\\ head -c 1024 /dev/urandom > file dd if=/dev/urandom of=file bs=100M count=1 iflag=fullblock # только печатные символы tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c 100M > file # либо base64 вместо tr, только менее гибко по символам base64 < /dev/urandom | head -c 1024 (1K/1M) # ${RANDOM} - возвращает случайное число 0..32К # случайное число от 1..10, (1+ чтобы небыло ноля) $(1 + ${RANDOM} % 10) # Еще так можно диапазон возвращать # 1..5, вернуть одно число $(shuf -i 1-5 -n 1)
Unix утилита для проверки типа файла и сравнения значений.
Возвращает 0 (истина) или 1 (ложь). Выражения могут быть как унарными так и бинарными.
# Использование test [expr] if test -f file.txt или [ -f file.txt ]; then rm file.txt else echo 'no found' fi # Проверка передачи файла в первом аргументе if (($# < 1)) || [ ! -f ${1} ]; then echo "Config file must be set in the first agrument" exit 1 fi # Если первый аргмент пустой или отсутствует if [ -z ${1} ]; then # Если второй аргумент НЕ пустой и не отсутствует if [ -n ${2} ]; then # Если отсутствует или пустые первый или второй аргументы if [ -z ${1} ] || [ -z ${2} ]; then
function_name() {command… }
Объявляются раньше вызова, нет возможности предобъявления
return возвращает только интовое значение, до 255
# Такая конструкция сохранит ПИД последнего запущенного процесса в файл & echo $! > file.pid
#!/bin/bash status=2 for i in 1 2 3 do # Для kill нужны права #if kill -0 `cat /path/file.pid` &> /dev/null; if ps -p `cat /path/file.pid` > /dev/null then status=0 break fi sleep 1 done echo "Service status is $status" exit $status
При условии что настроен беспарольный доступ
#!/bin/bash ssh username@my-host -p 2444 'bash -s' <<-'ENDSSH' if systemctl is-active --quiet "apache2"; then sudo systemctl stop apache2 sudo systemctl start nginx sudo systemctl status nginx else sudo systemctl stop nginx sudo systemctl start apache2 sudo systemctl status apache2 fi ENDSSH
Проверка процессов по списку PID
# Запуск фонового процесса с сохранением PID ($! для фонового процесса) (/usr/bin/sleep infinity &) && (echo $! > pids) for pid in `cat pids`; do if ! ps -p $pid > /dev/null; then echo "exit 1 for pid - $pid" exit 1 fi done