Bash Скрипты

Содержание
Введение
Простой скрипт
Переменные
:-
:=
Как вызвать скрипт
Как вызвать скрипт из скрипта
Как назвать скрипт
Результат команды в переменную
Аргументы из командной строки
Цикл for
Объединить строки
Функции
Проверить существование команды
Массивы
Похожие статьи

Введение

Перед тем как читать эту статью убедитесь, что вы знакомы с содержанием статьи «Основы Bash»

Основы

В начале скрипта нужно указать #!/bin/bash и желательно какой-то коментарий о назначении скрипта

#!/bin/bash # Пример комментария

Переменные

Создать переменную в Bash скрипте можно следующим образом

VAR=a echo $VAR

a

Можно воспользоваться кавычками

VAR="b" echo $VAR

b

VAR="c" echo "$VAR"

c

Присвоить одной переменной значение другой

VAR="c" echo "$VAR" VAR0="$VAR" echo "$VAR0"

c
c

Если первая переменная неопределена, ошибки не будет, но и присвоено ничего не будет

VAR1="$UNKNOWN" echo $VAR1

Хотелось бы, конечно, получать сообщения о необъявленных переменных.

:-

${parameter:-word}

   : If parameter is unset or null, the expansion of word is substituted.
   : Otherwise, the value of parameter is substituted.

С помощью :- можно задать значение по умолчанию. То есть, если первая переменная не определена, присвоится это значение.

Хорошо применять когда вам нужно присвоить значение переменной, но только в том случае, если его уже не присвоили ранее.

VAR1="value" NEW1=${VAR1:-text} NEW2=${VAR2:-text} echo "NEW1 = $NEW1" echo "NEW2 = $NEW2" echo "VAR1 = $VAR1" echo "VAR2 = $VAR2"

NEW1 = value NEW2 = text VAR1 = value VAR2 =

В первом случае переменная существовала, а во втором переменнйо VAR2 найти не удалось и было присвоено занчение text.

Обратите внимание, что сами переменные VAR1 и VAR2 не изменились

:=

${parameter:=word}

    If parameter is unset or null, the expansion of word is assigned to parameter.
    The value of parameter is then substituted.
    Positional parameters and special parameters may not be assigned to in this way.

:= ведёт себя похоже на :- но он в ещё и присваивает значение той переменной, которая была не задана

VAR1="value" NEW10=${VAR1:=foo} NEW20=${VAR2:=foo} echo "NEW10 = $NEW10" echo "NEW20 = $NEW20" echo "VAR1 = $VAR1" echo "VAR2 = $VAR2"

NEW10 = value NEW20 = foo VAR1 = value VAR2 = foo

Видно, что foo был использован не только для задания NEW20 но и для VAR2 которая не была определена

Как вызвать скрипт

Первым делом нужно убедиться, что файл script_1 является исполняемым

Если вы находитесь в той же диретории, что и script_1 выполните

ls -la

-rw-rw-r--. 1 andrei andrei 5252 Dec 03 08:11 script_1

Если четвёртый символ это - то файл не является исполняемым.

Сделать его исполняемым можно командой

chmod u+x script_1

ls -la

-rwxrw-r--. 1 andrei andrei 5252 Dec 03 08:11 script_1

Обратите внимание на -rwx теперь четвёртый символ это x

В моей CentOS настроена подсветка исполняемых файлов, поэтому он теперь зелёный

Теперь выполнить скрипт можно командой

./script_1

Конкретно этот скрипт должен принимать аргументы из командной строки , поэтому мы выполним

./script_1 word1 word2

word1 добавится в log.txt а word2 нет, потому что word1 это первый аргумент а word2 второй.

Чтобы записывать вообще все аргументы заменим $1 на $*

Добавим в лог время выполнения команд (подробности здесь)

#!/bin/bash # Читаем из терминала и записываем в лог echo $(date + "%Y-%m-%d %H:%M:%S,%3N") $* << ~/log.txt

./script_1 one two three
cat log.txt

2024-12-03 08:11:46,404 one two three

Как вызвать скрипт из другого скрипта

Допустим из скрипта parent.sh вам нужно вызвать скрипт child.sh

#!/bin/bash # parent bash ./child.sh

Это если они в одной директории, если в разных - пишите путь до скрипта

Как назвать скрипт

Проверить не занято ли имя системой можно командой type.

Например, вы решили назвать свой скрипт test

type test

test is a shell builtin

То есть имя занято, вы, конечно, можете его использовать, но с вызовом будут дополнительные сложности.

Вывод команды в переменную

Часто бывает нужно выполнить из скрипта команду и присвоить результат переменной.

Чтобы сделать это воспользуйтесь синтаксисом

ПЕРЕМЕННАЯ=$(КОМАНДА)

Например, вам нужно проанализировать лог на количество ошибок и предупреждений

#!/bin/bash ERROR=$(grep -o -i ERROR 2024-12-03-log.txt | wc -l) WARNING=$(grep -o -i WARNING 2024-12-03-log.txt | wc -l) echo "Ошибок: $ERROR; Предупреждений: $ WARNING"

wc это команда, которая подсчитывает число слов

Аргументы из командной строки

Скрипт может принимать аргументы из командной строки

Первый аргумент обозначается как $1 второй как $2 и так далее

Допустим мы хотим вызвать скрипт из файла script_1 и передать туда какую-то переменную, а затем записать её в лог

#!/bin/bash # Читаем из терминала и записываем в лог echo $1 << ~/log.txt

echo $1 означает, что мы возьмём первый аргументы

~/ означает, что файл log.txt будет в домашней директории

Рассмотрим пример ar.sh

#!/bin/bash AR=$1 echo $AR $AR $AR ~

Этот скрипт ждёт один внешний аргумент и присваивает его значение переменной AR

Затем это же значение выводится три раза

./ar.sh hei

hei hei hei

В C аналогичную функцию выполняет int argc, char* argv[]

В Python - sys.argv

Цикл for

В самом привычном виде цикл for можно записать так

#!/bin/bash for i in `seq 0 9`; do echo $i done

Объединить строки

Конкатенация строк может быть сделана следующим образом

concat.sh

#!/bin/bash STR1="heihei" STR2=".ru" STR3=$STR1$STR2 echo $STR3

./concat.sh

heihei.ru

Функции

Чтобы не писать длинные команды вручную можно объединить их в функции.

Например, нужно менять местами экраны с помощью xrandr это довольно длинная команда и чтобы не выполнять эту команду каждый раз после перезагрузки можно написать функцию в .bashrc

vi ~/.bashrc

function monitors_ { xrandr --output DP-1 --left-of eDP-1 }

Перезайдите в терминал.

Теперь, чтобы поменять экраны местами достаточно выполнить

monitors_

Ещё один пример - функция внутри обычного скрипта, пока что она просто возвращает hi

#!/bin/bash export LANG=en_US.UTF-8 say_hi(){ echo "hi" } say_hi

./say_hi

hi

Изменим код так, чтобы передать имя в функцию и поприветстовавать уже с этим именем

#!/bin/bash export LANG=en_US.UTF-8 say_hi(){ smb=$1 echo "hi "$smb } say_hi Andrei

./say_hi

hi Andrei

Пример функции, которая меняет разрешение изображения с помощью convert

#!/bin/bash WIDTH=1000 resize_image() { file=$1 EXT="${file##*.}" FULLNAME="${file##/}" echo $FULLNAME if [[ $EXT = "jpg" ]] || [[ $EXT = "png" ]]; then convert $FULLNAME -resize $WIDTH $FULLNAME fi } for file in ./*; do resize_image $file done

#!/bin/bash WIDTH=1000 resize_image() { file=$1 convert $FULLNAME -resize $WIDTH $FULLNAME } convert_to_webp() { file=$1 FILENAME="${file%.*}" FULLNAME_WEBP=$FILENAME".webp" if [[ ! -f $FULLNAME_WEBP ]]; then echo $FULLNAME_WEBP "doesn't exist - converting" cwebp -q 60 $file -o $FULLNAME_WEBP fi } for file in ./*; do EXT="${file##*.}" FULLNAME="${file##/}" echo $FULLNAME if [[ $EXT = "jpg" ]] || [[ $EXT = "png" ]]; then resize_image $file convert_to_webp $file fi done

Проверить существование команды

Проверить доступность или отсутствие команды можно с помощью command.

Например, проверка наличия firewall-cmd

if ! command -v firewall-cmd &> /dev/null then echo "firewall is not found" exit else echo "firewall is found" exit fi

Массивы

#!/bin/bash arr=(PNG JPG) for item in ${arr[@]} do echo $item done

PNG
JPG

Проверить есть ли в массиве определённый элемент

#!/bin/bash EXT=PNG arr=(PNG JPG) if [[ " ${arr[*]} " =~ " ${EXT} " ]]; then echo "Found" fi

Found

Похожие статьи
Bash
Основы Bash
alias: Псевдонимы
Bash Scripting
-eq -gt …: Операторы сравнения
if else: Условные операторы
Цикл while
date: Дата
Переход на новую строку
Арифметические операции
sftp: Передать файл или пароль в Bash скрипте
Мониторинг потребления памяти
Работа с файлами в директории
awk
grep
sed
Ошибки Bash
Zsh
Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@eth1.ru если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящуюю по тематике.
3. Хотите поддержать сайт материально
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......