Bash Скрипты
Введение
Перед тем как читать эту статью убедитесь, что вы знакомы с содержанием статьи «Основы Bash»
Основы
В начале скрипта нужно указать #!/bin/bash и желательно какой-то коментарий о назначении скрипта
#!/bin/bash
# Пример комментария
Переменные
Допустим мы хотим вызвать скрипт из файла script_1 и передать туда какую-то переменную, а затем записать её в лог
#!/bin/bash # Читаем из терминала и записываем в лог echo $1 << ~/log.txt
echo $1 означает, что мы возьмём первую переменную
~/ означает, что файл
log.txt
будет в домашней директории
Как вызвать скрипт
Первым делом нужно убедиться, что файл
script_1
является исполняемым
Если вы находитесь в той же диретории, что и
script_1
выполните
ls -la
-rw-rw-r--. 1 andrei andrei 5252 Sep 10 06:23 script_1
Если четвёртый символ это - то файл не является исполняемым.
Сделать его исполняемым можно командой
chmod u+x script_1
ls -la
-rwxrw-r--. 1 andrei andrei 5252 Sep 10 06:23 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-09-10 06:23:52,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-09-10-log.txt | wc -l)
WARNING=$(grep -o -i WARNING 2024-09-10-log.txt | wc -l)
echo "Ошибок: $ERROR; Предупреждений: $ WARNING"
wc это команда, которая подсчитывает число слов
Аргументы из командной строки
Скрипт может принимать аргументы из командной строки
Первый аргумент обозначается как $1 второй как $2 и так далее
Рассмотрим пример 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
Проверить существование команды
Проверить доступность или отсутствие команды можно с помощью command.
Например, проверка наличия
firewall-cmd
if ! command -v firewall-cmd &> /dev/null then echo "firewall is not found" exit else echo "firewall is found" exit fi