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

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


linux:binbash

Скриптинг

Первой строкой указывается т.н. shebang (#!) - последовательность двух символов, далее указывается путь к исполняющему файлу под-оболочки, так же, в этой строке можно передавать аргументы.
Если оболочка не указана явно, используется так же, что и запускает данный скрипт.

Для исполнения скрипта, у файла должно быть разрешение выполнения (+x), но если передать скрипт аргументом команде bash ./script, тогда бит необязателен.
exit - сообщает результат (0-успех) работы родительскому процессу, при отсутствии используется результат последней команды.

Аргументы (доступ к ним)

  • $? - код возврата последней выполнившейся команды
  • $$ - номер процесса последней команды ($! фоновой)
  • $№ - аргументы, по номеру. &0 - последний запущенный скрипт.
  • $# - кол-во переданных аргументов.
  • $* - все аргументы одной строкой.
  • $@ - все аргументы отдельной строкой.
  • $- - дейтствующие пар-ры команды set
  • shift - команда, после нее первый аргумент в $@ теряется, остальные сдвигаются влево.

Переменные

Пробелы не используются при определении
Знак доллара используется только при чтении значения, работа с переменной без этого знака.
В фигурных скобках более строгая форма ${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 - путь к исполняемому файлу bash.
  • $GROUPS - группы пользователя.
  • $HOME - домашний каталог.
  • $HOSTNAME - сетевое имя хоста.
  • $SHLVL - уровень вложенности shell.
  • $SECONDS - время работы скрипта.
  • $REPLY - для ввода read, по умолчанию.

Условие

Двойные квадратные скобки работают в целом так же, как и [одинарные квадратные скобки], но имеют дополнительные возможности вроде лучшей поддержки регулярных выражений.
Двойные круглые скобки это конструкция, позволяющая осуществлять арифметические вычисления внутри 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
:!: Old

Проверяет, является ли результат 0 (истина).
Условие условие проверяется с помощью команды 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
  • () или двойные - выполняет арифметическое действие внутри. Код возврата противоположен []

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

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

Else if (elif)

elif - краткая форма записи конструкции else if.

if [ expr ]; then
  action
elif [ expr ]; then
  action
else
  action
fi

Циклы

for

Обработка диапазонных значений.
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

Выполняется пока условие истинно.
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

Until

Противоположно циклу while, выполняется пока условие ложно. until условие do действие done. Все остальное аналогично.

case

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)

Утилита test

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

Параметры запуска

  • -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

Примеры

:!: Обширный пример

makeimport_sh.doc

:!: Проверка PID
# Такая конструкция сохранит ПИД последнего запущенного процесса в файл
& 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
:!: Выполнение скрипта на удаленной машине через SSH

При условии что настроен беспарольный доступ

#!/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
:!:
 
linux/binbash.txt · Последнее изменение: 2024/12/01 10:32 — admin