Автоматизация процессов. Запуск и остановка в Linux клиента pCloud по расписанию через скрипты bash. Пишем скрипты в Linux (обучение на примерах) Как это все работает

💖 Нравится? Поделись с друзьями ссылкой

Прежде всего давайте разберём, что такое script и для чего он нужен.

Script в переводе с английского - сценарий . Все мы смотрим фильмы, многие из нас - спектакли. Чтобы создать фильм/спектакль, сценаристы пишут к ним сценарии, на основании которых артисты, сценка за сценкой исполняют на сцене свои роли, из чего и складывается фильм/спектакль. Работа по созданию сценария довольно кропотливая, где нужно учесть всё до мелочей, чтобы в конечном итоге артисты могли выполнить задуманное сценаристом, а зритель увидел целостное произведение.

Подобным же образом пишутся скрипты для выполнения списка задач, которые пользователь составляет вместе (код), чтобы сделать их выполнение проще и быстрее в операционной системе. Для написания простых скриптов совсем не обязательно иметь образование программиста.

Для начала давайте создадим самый, что ни на есть, простейший скрипт-Shell для обновления системы.

Все действия я буду проводить с системе Ubuntu , но они применимы и к другим системам Linux , производных от Ubuntu . Для этого нам понадобятся: Текстовый редактор , чтобы наполнить его нужными задачами для создания скрипта (кода) и Терминал - для выполнения созданного скрипта. Эти инструменты установлены в любом дистрибутие Linux по умолчанию.

Итак, открываем текстовый редактор Gedit и вводим в него первые обязательные символы под названием shebang .
shebang в программировании, это последовательность из двух символов: решётки и восклицательного знака (#! ) в начале файла скрипта. И добавляем к данным символам без пробелов /bin/sh - интерпретатор, где будет выполняться скрипт. /bin/sh - это обычно Bourne shell или совместимый интерпретатор командной строки, который передаёт "path/to/script" как первый параметр.
Первая обязательная строка скрипта будет выглядеть следующим образом:

# Мой первый Script обновления Ubuntu

Знак решётки (#) в самом начале строки даёт понять интерпретатору/терминалу, что эту строку читать и выполнять не нужно. Строка нужна в коде данного скрипта для того чтобы сам создатель скрипта знал, что он собирается выполнить на данном отрезке/сценке в коде, чтобы не запутаться в дальнейшем, когда таких строк будет много. Такие строки с знаком решётки называются - закомментированные .

sudo apt update
sudo apt upgrade -y

-y в конце второй команды даёт понять интерпретатору/терминалу, что это действие/команду нужно выполнить автоматически, без дополнительного подтверждения пользователем, нажатия клавиши Ввод . y - сокращённо от английского yes , т.е. да .

Вот и всё. Ваш первый скрипт создан. У вас должно получиться как на снимке:


Остаётся сохранить созданный файл/скрипт и дать ему Имя с обязательным расширением в конце - .sh . Расширение .sh присваивается исполняемому файлу.
Я дал ему Имя - обновление.sh , сохранив в Домашней папке пользователя:


Для того чтобы созданный файл/скрипт был исполняемый, ему нужно дать на это разрешение. Сделать это можно двумя способами.

1. Выполнить следующую команду в терминале:

sudo chmod +x обновление.sh

2. Либо открыть файловый менеджер в Домашней папке (где вы сохранили созданный скрипт), правый клик на файле, в контекстном меню - Свойства - Права и активировать пункт - Выполнение : Разрешить выполнение файла как программы :


Чтобы выполнить созданный скрипт, нужно открыть терминал (о чём я писал в самом начале статьи, что терминал - необходимый атрибут/инструмент для выполнения скрипта), ввести sh , через пробел название скрипта - обновление.sh и нажать клавишу Ввод :


Либо в терминале вводим sh и перетаскиваем из файлового менеджера созданный файл с скриптом (также через пробел):


После того как путь к файлу отобразится после команды sh и пробела, достаточно нажать клавишу Enter (Ввод), чтобы выполнить обновление системы:


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

Да, кто-то может возразить, что обновление системы не сложно сделать выполнением этих двух команд в терминале, зачем пыжиться и создавать какие-то скрипты? Всё верно. Но это пример создания простейшего скрипта, чтобы показать, что "не боги горшки обжигают" 😃.

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

Многие из вас, скорее всего, пользуются сайтами по настройке системы, типа тех что я публикую после выхода очередного релиза Ubuntu - Ubuntu после установки или подобными сайтами. Откройте один из таких сайтов: http://compizomania.blogspot.com/2016/04/ubuntu-1604.html , затем текстовый редактор для создания скрипта.
Для примера я сделал следующую заготовку.

В текстовом редакторе вводим первую обязательную строку:

# Настройка Ubuntu после уставновки
# Обновление системы

Ниже следуют команды обновления системы:

sudo apt update
sudo apt upgrade -y

Строка описания: Добавление репозиториев:

# Добавление репозиториев

И добавляете необходимые репозитории для дальнейшей установки программного обеспечения:

sudo add-apt-repository "deb http://archive.canonical.com/ $(lsb_release -sc) partner" -y
sudo add-apt-repository ppa:atareao/telegram -y
sudo add-apt-repository ppa:atareao/atareao -y

sudo add-apt-repository ppa:nemh/systemback -y
sudo add-apt-repository ppa:gerardpuig/ppa -y
sudo add-apt-repository ppa:haecker-felix/gradio-daily -y

После того как необходимые репозитории добавлены (повторюсь, у вас могут быть свои репозитории, у меня пример), необходимо обновить систему:

Строка с описанием:

# Обновление системы после подключения репозиториев

И команда на выполнение:

sudo apt update

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

# Установка программ

Для установки программ достаточно один раз ввести команду sudo apt install , а затем через пробел в данную строку добавлять сколько угодно программ, главное чтобы они были правильно составлены. Если какая-то программа состоит из нескольких слов, её команда должна быть монолитной, т.е. все слова в ней должны вводится через чёрточку, например: unity-tweak-tool :

sudo apt install my-weather-indicator telegram skype lm-sensors hddtemp psensor gdebi systemback unity-tweak-tool ubuntu-cleaner gradio -y

Установка дополнительных кодеков

# Мультимедиа и кодеки

sudo apt install ubuntu-restricted-extras -y

Отключение о сбоях в системе

# Отключить отчёты о сбоях в системе

sudo sed -i "s/enabled=1/enabled=0/g" "/etc/default/apport"

Ну вот, пожалуй, и всё. Данный созданный файл сценария должен выглядеть следующим образом:


Необходимо сохранить его (нажать кнопку Сохранить ) и дать Имя с расширением .sh . Я назвал его Настройка\ Ubuntu.sh (вы можете назвать по-другому, но обязвтельно с расширением.sh):


Делаем созданный скрипт исполняемым:

sudo chmod +x Настройка\ Ubuntu.sh

Для выполнения созданного скрипта введите в терминале sh и название созданного скрипта через пробел, либо sh , пробел и перетащить в терминал созданный файл, как объяснялось ранее в простейшем скрипте и нажмите клавишу Ввод , для его выполнения.

Примечание . Обратный слэш в команде Настройка\ Ubuntu.sh экранирует пробел в названии файла для терминала между двумя отдельными словами.

После того как скрипт будет выполнен, хранить его на будущее, для возможной переустановки системы и повторной настройки, лучше всего на отдельном разделе ж/диска в папке /home . Если таковой нет, то в облачном сервисе (Облачное хранилище данных) типа: DropBox, Облако Mail.Ru, Mega.co и т.п., чтобы в любой момент воспользоваться скриптом самому, либо помочь знакомым или родственникам в настройке системы.

Создаём пустой файл.

Первой строкой пишем:

#!/bin/sh

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

Сохраним его под оригинальным названием (чтоб не совпадал с уже существующими) в каталоге /usr/sbin/.

Чтобы скрипт запускался при загрузке, необходимо прописать его в файле /etc/rc.local до строчки exit 0. Если у вас не существует данного файла, создайте его и вставьте в него следующее содержимое:

#!/bin/sh -e #Здесь вставляем строку с указанием вашего скрипта. /usr/sbin/mescripts exit 0

Немного более сложный способ

Позволяет задать последовательность загрузки и поведение скрипта при разных runlevel"ах.

Изучаем /etc/init.d/skeleton , на его основе создаем скрипт /etc/init.d/my_script , которым будет запускаться/останавливаться наше приложение.

В этих директориях лежат скрипты остановки сервисов:

/etc/rc0.d/ /etc/rc1.d/ /etc/rc6.d/

в этих - скрипты запуска сервисов:

/etc/rc2.d/ /etc/rc3.d/ /etc/rc4.d/ /etc/rc5.d/

Изучаем их на предмет последовательности (чем меньше первая цифра в начале скрипта, тем раньше запускается/останавливается приложение). Это может быть критично, если ваше приложение будет зависит от каких-то сервисов.

После того, как определились со скриптом запуска и очередностью, выполняем следующее:

Sudo update-rc.d my_script start 70 2 3 4 5 . stop 20 0 1 6 .

Здесь я определил, что мой скриптик должен запускаться попозже остальных(70), и останавливаться пораньше(20). Цифры 2 3 4 5 0 1 6 означают уровни загрузки.

Если что-то не понравилось - все можно удалить

Sudo update-rc.d -f my_script remove

Подробности в man update-rc.d .

Выполнение скрипта при включении/отключении сети

Есть директория /etc/network/ с поддиректориями if-down.d , if-pre-up.d , if-post-down.d , if-up.d . Если разместить скрипт в одной из этих поддиректорий, то он будет выполняться соответственно при выключении, перед включением, после выключения или при включении сети.

Другой способ - указать в файле /etc/network/interfaces одну из следующих директив: up , pre-up , post-up , down , pre-down , post-down . Например, строка

Post-up /path/to/script.sh

после включения сети выполнит скрипт script.sh . Подробнее можно почитать в man interfaces .

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

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

Набор скриптов автоматизирует процесс входа в систему и запускает PPP так что все, что вы должны сделать (от root или как член группы PPP) - дать одну команду запуска вашего соединения.

15.1 Скрипты соединения для аутентификации по имени/паролю пользователя

Если ваш ISP не требует использования PAP/CHAP, вам нужны именно эти скрипты!

Если пакет ppp установлен правильно, вы должны иметь два файла примеров. Для PPP 2.1.2 они находятся в /usr/sbin , а для PPP 2.2 они находятся в /etc/ppp/scripts . Они называются

для PPP-2. 1.2

а для PPP-2. 2

ppp-off ppp-on ppp-on-dialer

Теперь, если Вы используете PPP 2.1.2, я настойчиво прошу вас удалить файлы примеров. С ними имеются потенциальные проблемы (и не сообщайте мне, что они прекрасно работают), я использовал их очень долго (и даже рекомендовал их в первой версии этого HOWTO)!

Для пользователя PPP 2.1.2 имеется ЛУЧШАя версия шаблона, взятая из дистрибутива PPP 2.2. Я предлагаю вам скопировать и использовать эти скрипты вместо старого скрипта PPP-2.1.2.

15.2 Скрипт ppp-on

Это первый из ПАРЫ скриптов, которые фактически запускают соединение.

#!/bin/sh # # Скрипт для инициации соединения PPP. Это первая часть из пары скриптов. # Это не секретные скрипты, так как коды видны командой ps. # Однако это пример. # # Это параметры. Измените их как нужно. TELEPHONE=555-1212 # Телефонный номер соединения ACCOUNT=george # Имя пользователя для входа ("George Burns") PASSWORD=gracie # Пароль для этого аккаунта (и "Gracie Allen") LOCAL_IP=0.0.0.0 # Локальный IP адрес, если известен. Динамический = 0.0.0.0 REMOTE_IP=0.0.0.0 # Удаленный IP адрес, если желателен. Обычно 0.0.0.0 NETMASK=255.255.255.0 # Соответствующая сетевая маска, если нужна # # Экспортируем их, чтобы они были доступны в "ppp-on-dialer" export TELEPHONE ACCOUNT PASSWORD # # Это расположение скрипта, который звонит по телефону и регистрируется в # системе. Пожалуйста, используйте абсолютное имя файла, так как опция connect # не использует переменную $PATH. (Если это сделать, то "root" аккаунт будет # дырой в защите, так что не просите.) # DIALER_SCRIPT=/etc/ppp/ppp-on-dialer # # Инициация соединения # # exec /usr/sbin/pppd debug /dev/ttySx 38400 \ $LOCAL_IP:$REMOTE_IP \ connect $DIALER_SCRIPT

Это скрипт ppp-on-dialer:

#!/bin/sh # # Это вторая часть скрипта ppp-on. Она выполняет установку желаемого # соединения. # /usr/sbin/chat -v \ TIMEOUT 3 \ ABORT "\nBUSY\r" \ ABORT "\nNO ANSWER\r" \ ABORT "\nRINGING\r\n\r\nRINGING\r" \ "" \rAT \ "OK-+++\c-OK" ATH0 \ TIMEOUT 30 \ OK ATDT$TELEPHONE \ CONNECT "" \ ogin:--ogin: $ACCOUNT \ assword: $PASSWORD

Для PPP-2.2, сценарий ppp-off примерно такой:

#!/bin/sh ###################################################################### # # Определить прерываемое устройство. # if [ "$1" = "" ]; then DEVICE=ppp0 else DEVICE=$1 fi ###################################################################### # # Если pid файл ppp0 есть, тогда программа работает. Остановить ее. if [ -r /var/run/$DEVICE.pid ]; then kill -INT `cat /var/run/$DEVICE.pid` # # Если kill не работает, тогда нет процесса, запущенного под этим pid. # Это может также означать, что существует посторонний lock файл. # Возможно, вы захотите удалить его. if [ ! "$?" = "0" ]; then rm -f /var/run/$DEVICE.pid echo "ERROR: Removed stale pid file" exit 1 fi # # Отлично. Пусть pppd поправит свой собственный недочет. echo "PPP link to $DEVICE terminated." exit 0 fi # # для ppp0 не запущен ppp процесс echo "ERROR: PPP link is not active on $DEVICE" exit 1

15.3 Редактирование скриптов запуска PPP

Поскольку новые скрипты приходят двумя частями, мы в свою очередь отредактируем их.

Скрипт ppp-on

Вы должны будете отредактировать скрипт чтобы вставить ВАШЕ имя пользователя на вашем ISP, ВАШ пароль на вашем ISP, номер телефона вашего ISP.

Каждая из строк типа TELEPHONE= - это фактически установленные переменные shell, которые содержат информацию справа от = (исключая комментарии, конечно). Отредактируйте каждую из этих строк так, чтобы они соответствовали вашему ISP и соединению.

Также, поскольку вы устанавливаете IP адрес (если вам это нужно) в файле /etc/ppp/options , УДАЛИТЕ строку, которая говорит

$LOCAL_IP:$REMOTE_IP \

Также, удостоверьтесь, что переменная оболочки DIALER_SCRIPT указывает на полный путь и имя скрипта для дозвона, который вы фактически собираетесь использовать. Так что, если вы переместили его или переименовали скрипт, удостоверьтесь, что вы отредактировали эту строку правильно в скрипте ppp-on !

Сценарий ppp-on-dialer

Это второй скрипт, который фактически поднимает нашу ppp связь.

Обратите внимание: chat скрипт обычно однострочный. Наклонные черты влево используются, чтобы разместить строки на нескольких физических строках (для удобочитаемости человеком) и не формировать часть скрипта самому.

Однако, очень полезно рассмотреть это подробно так, чтобы мы поняли, что же фактически (предположительно) происходит!

15.4 Что означает скрипт chat...

Скрипт chat - последовательность пар ожидаемая строка посылаемая строка . В частности обратите внимание, что мы ВСЕГДА ожидаем что-нибудь перед тем, как пошлем что-либо.

Если мы должны послать что-то БЕЗ того, чтобы сначала получить что-нибудь, мы должны использовать пустую строку ожидания (обозначаемую "") и аналогично для ожидания чего-либо без того, чтобы посылания чего-нибудь! Также, если строка состоит из нескольких слов, (например, NO CARRIER), вы должны взять строку в кавычки, чтобы chat вопринял ее как одно целое.

Строка chat в нашем шаблоне:

Exec /usr/sbin/chat -v

В вызове chat опция -v говорит, чтобы chat копировал ВЕСЬ ввод/вывод в систеный лог (обычно /var/log/messages). Как только вы убедитесь, что скрипт chat работает надежно, отредактируйте эту строку, чтобы удалить -v , чтобы не хранить ненужную информацию в вашем syslog

Это устанавливает паузу для получения ожидаемого ввода в 3 секунды. Вы можете увеличить это значение до 5 или 10 секунд, если вы используете медленный модем!

ABORT "\nBUSY\r"

Если получена строка BUSY , то операция аварийно прекращается

ABORT "\nNO ANSWER\r"

Если получена строка NO ANSWER , то операция аварийно прекращается

ABORT "\nRINGING\r\n\r\nRINGING\r"

Если (повторимся) получена строка RINGING , то операция аварийно прекращается.

Это потому, что кто-то сидит на вашей телефонной линии!

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

OK-+++\c-OK ATH0

Это немного более сложно, поскольку использует некоторые из возможностей восстановления при ошибках chat .

What is says is... Ожидаем OK , если он не получен (потому что модем не в командном режиме), затем посылаем +++ (стандартная строка для Hayes-совместимых модемов, которая возвращает модем в командный режим) и ожидаем OK .

Затем посылаем ATH0 (строка для завершения связи модема). Это позволяет вашему скрипту справляться с вашим модемом, зависшим во время сеанса связи!

Установим паузу по времени в 30 секунд для оставшихся команд скрипта. Если вы испытываете проблемы со скриптом chat , прерывающимся из-за пауз, увеличьте это значение до 45 секунд или больше

OK ATDT$TELEPHONE

Ожидаем OK (ответ модема на команду ATH0) и набираем номер, на который мы хотим позвонить

Дожидаемся строки CONNECT (которую наш модем посылает, когда удаленные модем отвечает) и не посылаем в ответ ничего

Ogin:--ogin: $ACCOUNT

Снова, здесь мы вставляем кое-какое исправление ошибок. Ожидаем подсказку входа в систему (... ogin:), но если мы не получаем ее по истечении паузы, то посылаем возврат каретки и затем ищем подсказку входа в систему снова. Когда подсказка получена, посылаем username (сохраненное в переменной shell $ACCOUNT).

Assword: $PASSWORD

Ожидаем запроса пароля и посылаем наш пароль (аналогично сохраненный в переменной shell).

Этот скрипт chat имеет приемлемую возможность исправления ошибок. chat имеет значительно большее количество возможностей, чем показано здесь. Для подробной информации проконсультируйтесь с man chat (man 8 chat).

Запуск PPP на серверной стороне моединения

Хотя скрипт ppp-on-dialer отлично подходит для серверов, которые автоматически запускают pppd на серверной стороне как только вы зарегистрировались, некоторые серверы требуют, чтобы вы явно дали команду запуска PPP на сервере.

Если вы должны дать команду, чтобы запустить PPP на сервере, вы должны отредактировать скрипт ppp-on-dialer .

В КОНЦЕ сценария (после строки пароля) добавьте дополнительную пару ожидаемой-посылаемой строк, которая искала бы вашу подсказку регистрации в системе (отличая символы, которые имеют специальное значение в оболочке Bourne: типа $ и [ или ] (открытые и закрытые квадратные скобки).

Как только программа chat нашла командную строку оболочки, она должна выдать команду запуска ppp , требуемую для PPP сервера вашего ISP.

В моем случае, мой PPP сервер использует стандартную подсказку bash Linux

и требует, чтобы я напечатал

чтобы запустить PPP на сервере.

Хорошо бы учесть здесь некоторые ошибки, так например в моем случае я использую

Hartr--hartr ppp

Это значит, что если мы не получили подсказку в течении заданной паузы, то посылаем возврат каретки и ищем подсказку снова.

Как только подсказка получена, посылаем строку ppp .

Не забудьте добавить \ к концу предыдущей строки, так что бы chat думал, что весь сценарий chat состоит из одной строки!

К сожалению, на некоторых серверах набор подсказок часто меняется!

Возможно вам понадобится несколько раз зарегистрироваться, используя minicom, чтобы понять, что происходит, и найти устойчивую ожидаемую строку.

15.5 Сценарий chat для соединения PAP/CHAP

Если ваш ISP использует PAP/CHAP, то ваш сценарий chat намного более простой.

Весь ваш сценарий chat должен делать вот что: звонить по номеру телефона, ждать соединения и затем позволить pppd обработать регистрацию в системе!

#!/bin/sh # # This is part 2 of the ppp-on script. It will perform the connection # protocol for the desired connection. # exec /usr/sbin/chat -v \ TIMEOUT 3 \ ABORT "\nBUSY\r" \ ABORT "\nNO ANSWER\r" \ ABORT "\nRINGING\r\n\r\nRINGING\r" \ "" \rAT \ "OK-+++\c-OK" ATH0 \ TIMEOUT 30 \ OK ATDT$TELEPHONE \ CONNECT "" \

15.6 Отладка pppd и опция file option_file

Как мы уже видели, вы можете включить отладочную информацию опцией -d в pppd . Опция debug эквивалентна ей.

Поскольку мы устанавливаем новое соединение с новым скриптом, сейчас поставьте опцию отладки.

Если у вас мало дискового пространства, то логи pppd могут быстро увеличить ваш файл syslog и создать вам проблему.

Как только вы обрадуетесь, что все работает правильно, можете удалить эту опцию.

Если вы назвали ваш ppp файл опций как-нибудь иначе, чем /etc/ppp/options , или /etc/ppp/options.ttySx , определите имя файла опцией file в pppd , например

Exec /usr/sbin/pppd debug file options.myserver /dev/ttyS0 38400 \

Сегодня поговорим о bash-скриптах. Это - сценарии командной строки , написанные для оболочки bash. Существуют и другие оболочки, например - zsh, tcsh, ksh, но мы сосредоточимся на bash. Этот материал предназначен для всех желающих, единственное условие - умение работать в командной строке Linux.



Сценарии командной строки - это наборы тех же самых команд, которые можно вводить с клавиатуры, собранные в файлы и объединённые некоей общей целью. При этом результаты работы команд могут представлять либо самостоятельную ценность, либо служить входными данными для других команд. Сценарии - это мощный способ автоматизации часто выполняемых действий.

Итак, если говорить о командной строке, она позволяет выполнить несколько команд за один раз, введя их через точку с запятой:

Pwd ; whoami
На самом деле, если вы опробовали это в своём терминале, ваш первый bash-скрипт, в котором задействованы две команды, уже написан. Работает он так. Сначала команда pwd выводит на экран сведения о текущей рабочей директории, потом команда whoami показывает данные о пользователе, под которым вы вошли в систему.

Используя подобный подход, вы можете совмещать сколько угодно команд в одной строке, ограничение - лишь в максимальном количестве аргументов, которое можно передать программе. Определить это ограничение можно с помощью такой команды:

Getconf ARG_MAX
Командная строка - отличный инструмент, но команды в неё приходится вводить каждый раз, когда в них возникает необходимость. Что если записать набор команд в файл и просто вызывать этот файл для их выполнения? Собственно говоря, тот файл, о котором мы говорим, и называется сценарием командной строки.

Как устроены bash-скрипты

Создайте пустой файл с использованием команды touch . В его первой строке нужно указать, какую именно оболочку мы собираемся использовать. Нас интересует bash , поэтому первая строка файла будет такой:

#!/bin/bash
В других строках этого файла символ решётки используется для обозначения комментариев, которые оболочка не обрабатывает. Однако, первая строка - это особый случай, здесь решётка, за которой следует восклицательный знак (эту последовательность называют шебанг) и путь к bash , указывают системе на то, что сценарий создан именно для bash .

Команды оболочки отделяются знаком перевода строки, комментарии выделяют знаком решётки. Вот как это выглядит:

#!/bin/bash # This is a comment pwd whoami
Тут, так же, как и в командной строке, можно записывать команды в одной строке, разделяя точкой с запятой. Однако, если писать команды на разных строках, файл легче читать. В любом случае оболочка их обработает.

Установка разрешений для файла сценария

Сохраните файл, дав ему имя myscript , и работа по созданию bash-скрипта почти закончена. Сейчас осталось лишь сделать этот файл исполняемым, иначе, попытавшись его запустить, вы столкнётесь с ошибкой Permission denied .


Попытка запуска файла сценария с неправильно настроенными разрешениями

Сделаем файл исполняемым:

Chmod +x ./myscript
Теперь попытаемся его выполнить:

./myscript
После настройки разрешений всё работает как надо.


Успешный запуск bash-скрипта

Вывод сообщений

Для вывода текста в консоль Linux применяется команда echo . Воспользуемся знанием этого факта и отредактируем наш скрипт, добавив пояснения к данным, которые выводят уже имеющиеся в нём команды:

#!/bin/bash # our comment is here echo "The current directory is:" pwd echo "The user logged in is:" whoami
Вот что получится после запуска обновлённого скрипта.


Вывод сообщений из скрипта

Теперь мы можем выводить поясняющие надписи, используя команду echo . Если вы не знаете, как отредактировать файл, пользуясь средствами Linux, или раньше не встречались с командой echo , взгляните на этот материал.

Использование переменных

Переменные позволяют хранить в файле сценария информацию, например - результаты работы команд для использования их другими командами.

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

Существуют два типа переменных, которые можно использовать в bash-скриптах:

  • Переменные среды
  • Пользовательские переменные

Переменные среды

Иногда в командах оболочки нужно работать с некими системными данными. Вот, например, как вывести домашнюю директорию текущего пользователя:

#!/bin/bash # display user home echo "Home for the current user is: $HOME"
Обратите внимание на то, что мы можем использовать системную переменную $HOME в двойных кавычках, это не помешает системе её распознать. Вот что получится, если выполнить вышеприведённый сценарий.


Использование переменной среды в сценарии

А что если надо вывести на экран значок доллара? Попробуем так:

Echo "I have $1 in my pocket"
Система обнаружит знак доллара в строке, ограниченной кавычками, и решит, что мы сослались на переменную. Скрипт попытается вывести на экран значение неопределённой переменной $1 . Это не то, что нам нужно. Что делать?

В подобной ситуации поможет использование управляющего символа, обратной косой черты, перед знаком доллара:

Echo "I have \$1 in my pocket"
Теперь сценарий выведет именно то, что ожидается.


Использование управляющей последовательности для вывода знака доллара

Пользовательские переменные

В дополнение к переменным среды, bash-скрипты позволяют задавать и использовать в сценарии собственные переменные. Подобные переменные хранят значение до тех пор, пока не завершится выполнение сценария.

Как и в случае с системными переменными, к пользовательским переменным можно обращаться, используя знак доллара:
TNW-CUS-FMP - промо-код на 10% скидку на наши услуги, доступен для активации в течение 7 дней
#!/bin/bash # testing variables grade=5 person="Adam" echo "$person is a good boy, he is in grade $grade"
Вот что получится после запуска такого сценария.


Пользовательские переменные в сценарии

Подстановка команд

Одна из самых полезных возможностей bash-скриптов - это возможность извлекать информацию из вывода команд и назначать её переменным, что позволяет использовать эту информацию где угодно в файле сценария.

Сделать это можно двумя способами.

  • С помощью значка обратного апострофа «`»
  • С помощью конструкции $()
Используя первый подход, проследите за тем, чтобы вместо обратного апострофа не ввести одиночную кавычку. Команду нужно заключить в два таких значка:

Mydir=`pwd`
При втором подходе то же самое записывают так:

Mydir=$(pwd)
А скрипт, в итоге, может выглядеть так:

#!/bin/bash mydir=$(pwd) echo $mydir
В ходе его работы вывод команды pwd будет сохранён в переменной mydir , содержимое которой, с помощью команды echo , попадёт в консоль.


Скрипт, сохраняющий результаты работы команды в переменной

Математические операции

Для выполнения математических операций в файле скрипта можно использовать конструкцию вида $((a+b)) :

#!/bin/bash var1=$((5 + 5)) echo $var1 var2=$(($var1 * 2)) echo $var2


Математические операции в сценарии

Управляющая конструкция if-then

В некоторых сценариях требуется управлять потоком исполнения команд. Например, если некое значение больше пяти, нужно выполнить одно действие, в противном случае - другое. Подобное применимо в очень многих ситуациях, и здесь нам поможет управляющая конструкция if-then . В наиболее простом виде она выглядит так:

If команда then команды fi
А вот рабочий пример:

#!/bin/bash if pwd then echo "It works" fi
В данном случае, если выполнение команды pwd завершится успешно, в консоль будет выведен текст «it works».

Воспользуемся имеющимися у нас знаниями и напишем более сложный сценарий. Скажем, надо найти некоего пользователя в /etc/passwd , и если найти его удалось, сообщить о том, что он существует.

#!/bin/bash user=likegeeks if grep $user /etc/passwd then echo "The user $user Exists" fi
Вот что получается после запуска этого скрипта.


Поиск пользователя

Здесь мы воспользовались командой grep для поиска пользователя в файле /etc/passwd . Если команда grep вам незнакома, её описание можно найти .

В этом примере, если пользователь найден, скрипт выведет соответствующее сообщение. А если найти пользователя не удалось? В данном случае скрипт просто завершит выполнение, ничего нам не сообщив. Хотелось бы, чтобы он сказал нам и об этом, поэтому усовершенствуем код.

Управляющая конструкция if-then-else

Для того, чтобы программа смогла сообщить и о результатах успешного поиска, и о неудаче, воспользуемся конструкцией if-then-else . Вот как она устроена:

If команда then команды else команды fi
Если первая команда возвратит ноль, что означает её успешное выполнение, условие окажется истинным и выполнение не пойдёт по ветке else . В противном случае, если будет возвращено что-то, отличающееся от нуля, что будет означать неудачу, или ложный результат, будут выполнены команды, расположенные после else .

Напишем такой скрипт:

#!/bin/bash user=anotherUser if grep $user /etc/passwd then echo "The user $user Exists" else echo "The user $user doesn’t exist" fi
Его исполнение пошло по ветке else .


Запуск скрипта с конструкцией if-then-else

Ну что же, продолжаем двигаться дальше и зададимся вопросом о более сложных условиях. Что если надо проверить не одно условие, а несколько? Например, если нужный пользователь найден, надо вывести одно сообщение, если выполняется ещё какое-то условие - ещё одно сообщение, и так далее. В подобной ситуации нам помогут вложенные условия. Выглядит это так:

If команда1 then команды elif команда2 then команды fi
Если первая команда вернёт ноль, что говорит о её успешном выполнении, выполнятся команды в первом блоке then , иначе, если первое условие окажется ложным, и если вторая команда вернёт ноль, выполнится второй блок кода.

#!/bin/bash user=anotherUser if grep $user /etc/passwd then echo "The user $user Exists" elif ls /home then echo "The user doesn’t exist but anyway there is a directory under /home" fi
В подобном скрипте можно, например, создавать нового пользователя с помощью команды useradd , если поиск не дал результатов, или делать ещё что-нибудь полезное.

Сравнение чисел

В скриптах можно сравнивать числовые значения. Ниже приведён список соответствующих команд.
n1 -eq n2 Возвращает истинное значение, если n1 равно n2 .
n1 -ge n2 Возвращает истинное значение, если n1 больше или равно n2 .
n1 -gt n2 Возвращает истинное значение, если n1 больше n2 .
n1 -le n2 Возвращает истинное значение, если n1 меньше или равно n2 .
n1 -lt n2 Возвращает истинное значение, если n1 меньше n2 .
n1 -ne n2 Возвращает истинное значение, если n1 не равно n2 .

В качестве примера опробуем один из операторов сравнения. Обратите внимание на то, что выражение заключено в квадратные скобки.

#!/bin/bash val1=6 if [ $val1 -gt 5 ] then echo "The test value $val1 is greater than 5" else echo "The test value $val1 is not greater than 5" fi
Вот что выведет эта команда.


Сравнение чисел в скриптах

Значение переменной val1 больше чем 5, в итоге выполняется ветвь then оператора сравнения и в консоль выводится соответствующее сообщение.

Сравнение строк

В сценариях можно сравнивать и строковые значения. Операторы сравнения выглядят довольно просто, однако у операций сравнения строк есть определённые особенности, которых мы коснёмся ниже. Вот список операторов.
str1 = str2 Проверяет строки на равенство, возвращает истину, если строки идентичны.
s tr1 != str2 Возвращает истину, если строки не идентичны.
str1 < str2 Возвращает истину, если str1 меньше, чем str2 .
str1 > str2 Возвращает истину, если str1 больше, чем str2 .
-n str1 Возвращает истину, если длина str1 больше нуля.
-z str1 Возвращает истину, если длина str1 равна нулю.

Вот пример сравнения строк в сценарии:

#!/bin/bash user ="likegeeks" if [$user = $USER] then echo "The user $user is the current logged in user" fi
В результате выполнения скрипта получим следующее.


Сравнение строк в скриптах

Вот одна особенность сравнения строк, о которой стоит упомянуть. А именно, операторы «>» и «<» необходимо экранировать с помощью обратной косой черты, иначе скрипт будет работать неправильно, хотя сообщений об ошибках и не появится. Скрипт интерпретирует знак «>» как команду перенаправления вывода.

Вот как работа с этими операторами выглядит в коде:

#!/bin/bash val1=text val2="another text" if [ $val1 \>
Вот результаты работы скрипта.


Сравнение строк, выведенное предупреждение

Обратите внимание на то, что скрипт, хотя и выполняется, выдаёт предупреждение:

./myscript: line 5: [: too many arguments
Для того, чтобы избавиться от этого предупреждения, заключим $val2 в двойные кавычки:

#!/bin/bash val1=text val2="another text" if [ $val1 \> "$val2" ] then echo "$val1 is greater than $val2" else echo "$val1 is less than $val2" fi
Теперь всё работает как надо.


Сравнение строк

Ещё одна особенность операторов «>» и «<» заключается в том, как они работают с символами в верхнем и нижнем регистрах. Для того, чтобы понять эту особенность, подготовим текстовый файл с таким содержимым:

Likegeeks likegeeks
Сохраним его, дав имя myfile , после чего выполним в терминале такую команду:

Sort myfile
Она отсортирует строки из файла так:

Likegeeks Likegeeks
Команда sort , по умолчанию, сортирует строки по возрастанию, то есть строчная буква в нашем примере меньше прописной. Теперь подготовим скрипт, который будет сравнивать те же строки:

#!/bin/bash val1=Likegeeks val2=likegeeks if [ $val1 \> $val2 ] then echo "$val1 is greater than $val2" else echo "$val1 is less than $val2" fi
Если его запустить, окажется, что всё наоборот - строчная буква теперь больше прописной.


Команда sort и сравнение строк в файле сценария

В командах сравнения прописные буквы меньше строчных. Сравнение строк здесь выполняется путём сравнения ASCII-кодов символов, порядок сортировки, таким образом, зависит от кодов символов.

Команда sort , в свою очередь, использует порядок сортировки, заданный в настройках системного языка.

Проверки файлов

Пожалуй, нижеприведённые команды используются в bash-скриптах чаще всего. Они позволяют проверять различные условия, касающиеся файлов. Вот список этих команд.
-d file Проверяет, существует ли файл, и является ли он директорией.
-e file Проверяет, существует ли файл.
-f file Проверяет, существует ли файл, и является ли он файлом.
-r file Проверяет, существует ли файл, и доступен ли он для чтения.
-s file П роверяет, существует ли файл, и не является ли он пустым.
-w file Проверяет, существует ли файл, и доступен ли он для записи.
-x file Проверяет, существует ли файл, и является ли он исполняемым.
file1 -nt file2 Проверяет, новее ли file1 , чем file2 .
file1 -ot file2 Проверяет, старше ли file1 , чем file2 .
-O file Проверяет, существует ли файл, и является ли его владельцем текущий пользователь.
-G file Проверяет, существует ли файл, и соответствует ли его идентификатор группы идентификатору группы текущего пользователя.

Эти команды, как впрочем, и многие другие рассмотренные сегодня, несложно запомнить. Их имена, являясь сокращениями от различных слов, прямо указывают на выполняемые ими проверки.

Опробуем одну из команд на практике:

#!/bin/bash mydir=/home/likegeeks if [ -d $mydir ] then echo "The $mydir directory exists" cd $ mydir ls else echo "The $mydir directory does not exist" fi
Этот скрипт, для существующей директории, выведет её содержимое.


Вывод содержимого директории

Полагаем, с остальными командами вы сможете поэкспериментировать самостоятельно, все они применяются по тому же принципу.

Итоги

Сегодня мы рассказали о том, как приступить к написанию bash-скриптов и рассмотрели некоторые базовые вещи. На самом деле, тема bash-программирования огромна. Эта статья является переводом первой части большой серии из 11 материалов. Если вы хотите продолжения прямо сейчас - вот список оригиналов этих материалов. Для удобства сюда включён и тот, перевод которого вы только что прочли.

Пишем скрипты в Linux (обучение на примерах)

———————————————————————————-

1. Введение

Что нужно, чтобы писать скрипты
Владение инструментами командной строки и их необходимыми опциями.
Базовые знания английского языка уровня начальной школы не помешают.

Зачем нужны скрипты
Во-первых, администрирование linux-сервера в той или иной степени сводится к систематическому выполнению одних и тех же команд. Причем не обязательно, чтобы эти команды выполнял человек. Их можно запрограммировать на выполнение машиной.
Во-вторых, даже просто выполнение обычной задачи, которая (вдруг) составляет 20-1000… однообразных операций ГОРАЗДО проще реализовать в скрипте.

Что такое скрипт
Скрипт — набор инструкций, которые должен в определенном порядке и в определенное время выполнить компьютер. Инструкциями могут быть как внутренние команды оболочки (циклы, условия, обработка текстовой информации, работа с переменными окружения и прочее), так и любая программа, выполняемая нами в консоли с необходимыми параметрами.

Как писать скрипт
В нашем случае скрипт будет представлять из себя текстовый файл с атрибутами выполнения. Если файл сценария начинается с последовательности #!, которая в мире UNIX называется sha-bang, то это указывает системе какой интерпретатор следует использовать для исполнения сценария. Если это трудно понять, то просто запомните, что все скрипты мы будем начинать писать именно со строчки #!/bin/bash или #!/bin/sh, а далее пойдут команды и комментарии к ним.

Напутствие
Я Вам искренне советую писать как можно больше комментариев чуть ли ни к каждой строчке в скрипте. Пройдет время и Вам понадобится изменить или модернизировать написанный когда-то скрипт. Если не помнишь или не понимаешь, что написано в скрипте, то становится сложно его изменять, проще писать с нуля.

Какие скрипты могут нам понадобиться:

    устанавливающий правила файервола при загрузке системы.
    выполняющий backup настроек и данных.
    запускающий в определенное время (лучше каждую ночь) программу, которая сканирует логи прокси-сервера и выдает удобный web-отчет по количеству скачанного трафика.
    отправляющий нам на почту информацию о том, что кто-то получил доступ к нашему серверу по ssh, время подключения и адрес клиента.

О методике написания скриптов
Создаем текстовый файл, редактируем его, устанавливаем права на выполнение, запускаем, смотрим ошибки, исправляем, запускаем, смотрим ошибки…
Когда все вылизано и работает правильно, ставим его в автозагрузку либо в планировщик на определенное время.

———————————————————————————-

2. Обучение написанию сценариев на внутреннем языке BASH
оригинал: https://www.linuxconfig.org/Bash_scripting_Tutorial

Это руководство предполагает отсутствие предварительных знаний о методике написания сценариев (далее скриптов) с помощью внутреннего языка Bash. С помощью данного руководства вы обнаружите в скором времени, что написание скриптов очень простая задача. Давайте начнем наше обучение с простого сценария, выполняющего вывод строки «Hello World!» (в перев. с англ. — Всем привет!)

1. Сценарий «Всем привет»
Вот ваш первый пример bash-скрипта:

#!/bin/bash
echo «Hello World»

Переходим в директорию, содержащую наш файл hello_world.sh и делаем его исполняемым:

Код: Выделить всё $ chmod +x hello_world.sh

Запускаем скрипт на выполнение

Код: Выделить всё $ ./hello_world.sh

2. Простой архивирующий bash-скрипт

#!/bin/bash
tar -czf myhome_directory.tar.gz /home/user

Код: Выделить всё $ ./backup.sh

$ du -sh myhome_directory.tar.gz
41M myhome_directory.tar.gz

3. Работа с переменными
В данном примере мы объявляем простую переменную и выводим её на экран с помощью команды echo

#!/bin/bash
STRING=»HELLO WORLD!!!»
echo $STRING

Код: Выделить всё $ ./hello_world.sh
HELLO WORLD!!!

Наш архивирующий скрипт с переменными:

#!/bin/bash
OF=myhome_directory_$(date +%Y%m%d).tar.gz
IF=/home/user
tar -czf $OF $IF

Код: Выделить всё $ ./backup.sh
tar: Removing leading "\" from member names
$ du -sh *tar.gz
41M myhome_directory_20100123.tar.gz

3.1 Глобальные и локальные переменные

#!/bin/bash
# Объявляем глобальную переменную
# Такая переменная может использоваться в любом месте этого скрипта
VAR=»global variable»
function bash {
# Объявляем локальную переменную
# Такая переменная действительна только для функции, в которой её объявили
local VAR=»local variable»
echo $VAR
}
echo $VAR
bash
# Обратите внимание, что глобальная переменная не изменилась
echo $VAR

Код: Выделить всё $ ./variables.sh
global variable
local variable
global variable

4. Передаем аргументы в скрипт

#!/bin/bash
# Используйте предопределенные переменные для доступа к аргументам
# Выводим аргументы на экран
echo $1 $2 $3 ‘ -> echo $1 $2 $3’

#Мы так же можем получить доступ к аргументам через специальный массив args=(«$@»)
# Выводим аргументы на экран
echo ${args} ${args} ${args} ‘ -> args=(«$@»); echo ${args} ${args} ${args}’

# Используйте переменную $@ для вывода всех аргументов сразу
echo $@ ‘ -> echo $@’

Используйте переменную $# для вывода количества переданный в скрипт аргументов
echo Number of arguments passed: $# ‘ -> echo Number of arguments passed: $#’

Код: Выделить всё $ ./arguments.sh Bash Scripting Tutorial
Bash Scripting Tutorial -> echo $1 $2 $3
Bash Scripting Tutorial -> args=("$@"); echo ${args} ${args} ${args}
Bash Scripting Tutorial -> echo $@
Number of arguments passed: 3 -> echo Number of arguments passed: $#

5. Выполнение в скрипте команд оболочки

#!/bin/bash
# используйте обратные кавычки » ` ` » для выполнения команды оболочки
echo `uname -o`
# теперь попробуем без кавычек
echo uname -o

Код: Выделить всё $ uname -o
GNU/Linux
$ ./bash_backtricks.sh
GNU/Linux
uname -o

Как видим, во втором случае вывелась сама команда, а не результат её выполнения

6. Читаем пользовательский ввод (интерактивность)

#!/bin/bash
echo -e «Hi, please type the word: \c »
read word
echo «The word you entered is: $word»
echo -e «Can you please enter two words? »
read word1 word2
echo «Here is your input: \»$word1\» \»$word2\»»
echo -e «How do you feel about bash scripting? »
# read command now stores a reply into the default build-in variable $REPLY
read
echo «You said $REPLY, I’m glad to hear that! »
echo -e «What are your favorite colours ? »
# -a makes read command to read into an array
read -a colours
echo «My favorite colours are also ${colours}, ${colours} and ${colours}:-)»

Код: Выделить всё $ ./read.sh
Hi, please type the word: something
The word you entered is: something
Can you please enter two words?
Debian Linux
Here is your input: "Debian" "Linux"
How do you feel about bash scripting?
good
You said good, I"m glad to hear that!
What are your favorite colours ?
blue green black
My favorite colours are also blue, green and black:-)

7. Использование ловушки

#!/bin/bash
# объявляем ловушку
trap bashtrap INT
# очищаем экран
clear;
# функция ловушки выполняется, когда пользователь нажимает CTRL-C:
# На экран будет выводиться => Executing bash trap subrutine !
# но скрипт будет продолжать выполняться
bashtrap()
{
echo «CTRL+C Detected !…executing bash trap !»
}
# скрипт будет считать до 10
for a in `seq 1 10`; do
echo «$a/10 to Exit.»
sleep 1;
done
echo «Exit Bash Trap Example!!!»

Код: Выделить всё $ ./trap.sh
1/10
2/10
3/10
4/10
5/10
6/10

7/10
8/10
9/10
CTRL+C Detected !...executing bash trap !
10/10
Exit Bash Trap Example!!!

Как видим, сочетание клавишь Ctrl-C не остановило выполнение скрипта.

8. Массивы
8.1 Объявляем простой массив

#!/bin/bash
# Объявляем простой массив с 4 элементами
ARRAY=(‘Debian Linux’ ‘Redhat Linux’ Ubuntu Linux)
# Получаем количество элементов в массиве
ELEMENTS=${#ARRAY[@]}

# выводим в цикле каждый элемент массива
for ((i=0;i<$ELEMENTS;i++)); do
echo ${ARRAY[${i}]}
done

Код: Выделить всё $./arrays.sh
Debian Linux
Redhat Linux
Ubuntu
Linux

8.2 Заполняем массив значениями из файла

#!/bin/bash
# Объявляем массив
declare -a ARRAY
# Команда exec # stdin (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать
# содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.
exec 10 let count=0

while read LINE <&10; do

ARRAY[$count]=$LINE
((count++))
done

echo Number of elements: ${#ARRAY[@]}
# Вывод значений массива
echo ${ARRAY[@]}
# закрываем файл
exec 10>&-

Код: Выделить всё $ cat bash.txt
Debian Linux
Redhat Linux
Ubuntu
Linux
$ ./arrays.sh
Number of elements: 4
Debian Linux Redhat Linux Ubuntu Linux

9. Условия «если-то-иначе»
9.1. Простое использование «если-иначе» условий
Обратите внимание на пробелы в квадратных скобках, без которых условие работать не будет.

#!/bin/bash
directory=»./BashScripting»

# проверяем наличие директории
if [ -d $directory ]; then
echo «Directory exists»
else
echo «Directory does not exists»
fi

Код: Выделить всё $ ./if_else.sh
Directory does not exists
$ mkdir BashScripting
$ ./if_else.sh
Directory exists

9.2 Вложенные «если-иначе» условия

#!/bin/bash
# Объявляем переменную со значением 4
choice=4
# Выводим на экран
echo «1. Bash»
echo «2. Scripting»
echo «3. Tutorial»

# Выполняем, пока переменная равна четырем
# Зацикливание
while [ $choice -eq 4 ]; do

# читаем пользовательский ввод
read choice
# вложенное «если-иначе» условие
if [ $choice -eq 1 ] ; then

echo «You have chosen word: Bash»

if [ $choice -eq 2 ] ; then
echo «You have chosen word: Scripting»
else

if [ $choice -eq 3 ] ; then
echo «You have chosen word: Tutorial»
else
echo «Please make a choice between 1-3 !»
echo «1. Bash»
echo «2. Scripting»
echo «3. Tutorial»
echo -n «Please choose a word ? »
choice=4
fi
fi
fi
done

Код: Выделить всё $ ./nested.sh
1. Bash
2. Scripting
3. Tutorial

5

1. Bash
2. Scripting
3. Tutorial
Please choose a word ?
4
Please make a choice between 1-3 !
1. Bash
2. Scripting
3. Tutorial
Please choose a word ?
3
You have chosen word: Tutorial

Таким образом сначала тело цикла «while» выполняется, т.к. переменная choice изначально равна четырем. Потом читаем в неё пользовательский ввод, и если ввод не равен 1,2 или 3 то делаем нашу переменную снова равную 4, в связи с чем тело цикла повторяется (снова необходимо вводить 1,2 или 3).

10. Сравнения
10.1 Арифметические сравнения

Lt <
-gt >
-le <=
-ge >=
-eq ==
-ne !=

#!/bin/bash

NUM1=2
NUM2=2
if [ $NUM1 -eq $NUM2 ]; then
echo «Both Values are equal»
else
echo «Values are NOT equal»
fi

Код: Выделить всё $ ./equals.sh
Both Values are equal

#!/bin/bash
# Объявляем переменные с целочисленными значениями
NUM1=2
NUM2=3
if [ $NUM1 -eq $NUM2 ]; then
echo «Both Values are equal»
else
echo «Values are NOT equal»
fi

Код: Выделить всё $ ./equals.sh
Values are NOT equal

#!/bin/bash
# Объявляем переменные с целочисленными значениями
NUM1=2
NUM2=1
if [ $NUM1 -eq $NUM2 ]; then
echo «Both Values are equal»
elif [ $NUM1 -gt $NUM2 ]; then
echo «$NUM1 is greater then $NUM2»
else
echo «$NUM2 is greater then $NUM1»
fi

Код: Выделить всё $ ./equals.sh
2 is greater then 1

10.2 Символьно-текстовые сравнения

Одинаковые
!= не одинаковые
< меньще чем
> больше чем
-n s1 переменная s1 не пустая
-z s1 переменная s1 пустая

#!/bin/bash

S1=»Bash»

S2=»Scripting»
if [ $S1 = $S2 ]; then

else
echo «Strings are NOT equal»
fi

Код: Выделить всё $ ./statement.sh
Strings are NOT equal

#!/bin/bash
# Объявляем символьную переменную S1
S1=»Bash»
# Объявляем символьную переменную S2
S2=»Bash»
if [ $S1 = $S2 ]; then
echo «Both Strings are equal»
else
echo «Strings are NOT equal»
fi

Код: Выделить всё $ ./statement.sh
Both Strings are equal

11. Проверка файлов

B filename Block special file
-c filename Special character file
-d directoryname Check for directory existence
-e filename Check for file existence
-f filename Check for regular file existence not a directory
-G filename Check if file exists and is owned by effective group ID.
-g filename true if file exists and is set-group-id.
-k filename Sticky bit
-L filename Symbolic link
-O filename True if file exists and is owned by the effective user id.
-r filename Check if file is a readable
-S filename Check if file is socket
-s filename Check if file is nonzero size
-u filename Check if file set-ser-id bit is set
-w filename Check if file is writable
-x filename Check if file is executable

#!/bin/bash
file=»./file»
if [ -e $file ]; then
echo «File exists»
else
echo «File does not exists»
fi

Код: Выделить всё $ ls
file.sh
$ ./file.sh
File does not exists
$ touch file
$ ls
file file.sh
$ ./file.sh
File exists

Аналогично для примера мы можем использовать «в то время как» петли, чтобы проверить, если файл не существует. Этот сценарий будет спать, пока файл не существует. Обратите внимание на Bash отрицатель «!» что сводит на нет (инвертирует) -e опцию.

12. Циклы
12.1. Цикл For

#!/bin/bash
# for цикл
for f in $(ls /var/); do
echo $f
done

Запуск for-цикла из командной строки bash:

Код: Выделить всё $ for f in $(ls /var/); do echo $f; done Код: Выделить всё $ for f in $(ls /var/); do echo $f; done
backups
cache
crash
games
lib
local
lock
log
mail
opt
run
spool
tmp
www

12.2. While цикл

#!/bin/bash
COUNT=6
# while цикл
while [ $COUNT -gt 0 ]; do

let COUNT=COUNT-1
done

Код: Выделить всё $ ./while_loop.sh
Value of count is: 6
Value of count is: 5
Value of count is: 4
Value of count is: 3
Value of count is: 2
Value of count is: 1

12.3. Until цикл

#!/bin/bash
COUNT=0
# until цикл
until [ $COUNT -gt 5 ]; do
echo Value of count is: $COUNT
let COUNT=COUNT+1
done

Код: Выделить всё $ ./until_loop.sh
Value of count is: 0
Value of count is: 1
Value of count is: 2
Value of count is: 3
Value of count is: 4
Value of count is: 5

12.4. Циклы с неявными условиями
В следующем примере условием while-цикла является наличие стандартного ввода.
Тело цикла будет выполняться пока есть чему перенаправляться из стандартного вывода в команду read.

#!/bin/bash
# Данный скрипт будет искать и удалять пробелы
# в файлах, заменяя их на подчеркивания
DIR=».»
Управление циклом с командой read путем перенаправления вывода в цикле.
find $DIR -type f | while read file; do
# используем POSIX-класс [:space:] чтобы найти пробелы в именах файлов
if [[ «$file» = *[[:space:]]* ]]; then
# замена пробелов подчеркиваниями
mv «$file» `echo $file | tr ‘ ‘ ‘_’`
fi;
done

Код: Выделить всё $ ls -1
script.sh
$ touch "file with spaces"
$ ls -1
file with spaces
script.sh
$ ./script.sh
$ ls -1
file_with_spaces
script.sh

13. Функции

#!/bin/bash
# Функции могут быть объявлены в любом порядке
function function_B {
echo Function B.
}
function function_A {
echo $1
}
function function_D {
echo Function D.
}
function function_C {
echo $1
}
# Вызываем функции
# передаем параметр в функцию function A
function_A «Function A.»
function_B
# передаем параметр в функцию function C
function_C «Function C.»
function_D

Код: Выделить всё $ ./functions.sh
Function A.
Function B.
Function C.
Function D.

14. Оператор выбора — Select

#!/bin/bash
PS3=’Choose one word: ‘
# select
select word in «linux» «bash» «scripting» «tutorial»
do
echo «The word you have selected is: $word»
# Прерываем, в противном случае цикл будет бесконечный.
break
done
exit 0

Код: Выделить всё $ ./select.sh
1) linux
2) bash
3) scripting
4) tutorial
Choose one word: 4
The word you have selected is: tutorial

15. Оператор выбора — Case

#!/bin/bash
echo «What is your preferred programming / scripting language»
echo «1) bash»
echo «2) perl»
echo «3) phyton»
echo «4) c++»
echo «5) I do not know !»
read case;
# простая структура case-выбора
# обратите внимание, что в данном примере $case — всего лишь переменная
# и не обязана так называться. Это лишь пример
case $case in
1) echo «You selected bash»;;
2) echo «You selected perl»;;
3) echo «You selected phyton»;;
4) echo «You selected c++»;;
5) exit
esac

Код: Выделить всё $ ./case.sh
What is your preferred programming / scripting language
1) bash
2) perl
3) phyton
4) c++
5) I do not know !
4
You selected c++

———————————————————————————-

Более подробную информацию можно получить из различных источников, например отсюда
оригинал: https://www.linuxconfig.org/Bash_scripting_Tutorial
https://ruslandh.narod.ru/howto_ru/Bash-Prog-Intro/
https://bug.cf1.ru/2005-03-17/programmin … -book.html

https://ubuntologia.ru/forum/viewtopic.php?f=109&t=2296

Рассказать друзьям