Bash-скрипти: початок

Bash-скрипти: початок
Bash-скрипти, частина 2: цикли
Bash-скрипти, частина 3: параметри та ключі командного рядка
Bash-скрипти, частина 4: введення та виведення
Bash-скрипти, частина 5: сигнали, фонові завдання, керування сценаріями
Bash-скрипти, частина 6: функції та розробка бібліотек
Bash-скрипти, частина 7: sed та обробка текстів
Bash-скрипти, частина 8: мова обробки даних awk
Bash-скрипти, частина 9: регулярні вирази
Bash-скрипти, частина 10: практичні приклади
Bash-скрипти, частина 11: expect та автоматизація інтерактивних утиліт

Сьогодні поговоримо про bash-скрипти. Це - сценарії командного рядка, написані для bash оболонки. Існують інші оболонки, наприклад — zsh, tcsh, ksh, але ми зосередимося на bash. Цей матеріал призначений для всіх бажаючих, єдина умова - вміння працювати в командному рядку Linux

Bash-скрипти: початок

Сценарії командного рядка - це набори тих самих команд, які можна вводити з клавіатури, зібрані у файли і об'єднані якоюсь спільною метою. У цьому результати роботи команд можуть бути або самостійну цінність, або бути вхідними даними інших команд. Сценарії - це потужний спосіб автоматизації дій, що часто виконуються.

Bash-скрипти: початок

Отже, якщо говорити про командний рядок, вона дозволяє виконати кілька команд за один раз, ввівши їх через крапку з комою:

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.

Bash-скрипти: початок
Спроба запуску сценарійного файлу з неправильно налаштованими дозволами

Зробимо файл виконуваним:

chmod +x ./myscript

Тепер спробуємо його виконати:

./myscript

Після налаштування дозволів все працює як слід.

Bash-скрипти: початок
Успішний запуск bash-скрипту

Виведення повідомлень

Для виведення тексту в консоль Linux застосовується команда echo. Скористаємося знанням цього факту і відредагуємо наш скрипт, додавши пояснення до даних, які виводять команди, які вже є в ньому:

#!/bin/bash
# our comment is here
echo "The current directory is:"
pwd
echo "The user logged in is:"
whoami

Ось що вийде після запуску оновленого сценарію.

Bash-скрипти: початок
Виведення повідомлень із скрипту

Тепер ми можемо виводити написи, що пояснюють, використовуючи команду echo. Якщо ви не знаєте, як відредагувати файл, використовуючи засоби Linux, або раніше не зустрічалися з командою echo, погляньте на цей матеріал.

Використання змінних

Змінні дозволяють зберігати у файлі сценарію інформацію, наприклад результати роботи команд для використання їх іншими командами.

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

Існують два типи змінних, які можна використовувати в bash-скриптах:

  • Змінні середовища
  • Користувальницькі змінні

Змінні середовища

Іноді в командах оболонки необхідно працювати з деякими системними даними. Ось, наприклад, як вивести домашню директорію поточного користувача:

#!/bin/bash
# display user home
echo "Home for the current user is: $HOME"

Зверніть увагу на те, що ми можемо використовувати системну змінну $HOME у подвійних лапках, це не завадить системі її розпізнати. Ось що вийде, якщо виконати наведений вище сценарій.

Bash-скрипти: початок
Використання змінного середовища у сценарії

А якщо треба вивести на екран значок долара? Спробуємо так:

echo "I have $1 in my pocket"

Система виявить знак долара у рядку, обмеженому лапками, і вирішить, що ми послалися на змінну. Скрипт спробує вивести на екран значення невизначеної змінної $1. Це не те, що нам потрібне. Що робити?

У подібній ситуації допоможе використання символу керуючого, зворотної косої риси, перед знаком долара:

echo "I have $1 in my pocket"

Тепер сценарій виведе саме те, що очікується.

Bash-скрипти: початок
Використання послідовності, що управляє, для виведення знака долара

Користувальницькі змінні

Крім змінних середовища, 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-скрипти: початок
Змінні користувача у сценарії

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

Одна з найкорисніших можливостей bash-скриптів - це можливість витягувати інформацію з виведення команд і призначати її змінним, що дозволяє використовувати цю інформацію будь-де у файлі сценарію.

Зробити це можна двома способами.

  • За допомогою піктограми зворотного апострофа «`»
  • За допомогою конструкції $()

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

mydir=`pwd`

При другому підході те саме записують так:

mydir=$(pwd)

А скрипт, зрештою, може виглядати так:

#!/bin/bash
mydir=$(pwd)
echo $mydir

У ході його роботи виведення команди pwdбуде збережено у змінній mydir, вміст якої за допомогою команди echo, потрапить у консоль

Bash-скрипти: початок
Скрипт, що зберігає результати роботи команди у змінній

Математичні операції

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

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

Bash-скрипти: початок
Математичні операції у сценарії

Керуюча конструкція 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

Ось що виходить після запуску цього сценарію.

Bash-скрипти: початок
Пошук користувача

Тут ми скористалися командою 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.

Bash-скрипти: початок
Запуск скрипту з конструкцією 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

Ось що виведе ця команда.

Bash-скрипти: початок
Порівняння чисел у скриптах

Значення змінної val1більше ніж 5, в результаті виконується гілка thenоператора порівняння та в консоль виводиться відповідне повідомлення.

Порівняння рядків

У сценаріях можна порівнювати рядкові значення. Оператори порівняння виглядають досить просто, проте операції порівняння рядків мають певні особливості, яких ми торкнемося нижче. Ось перелік операторів.

str1 = str2 Перевіряє рядки на рівність, повертає істину, якщо ідентичні рядки.
str1 != 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

В результаті виконання скрипту отримаємо таке.

Bash-скрипти: початок
Порівняння рядків у скриптах

Ось одна особливість порівняння рядків, про яку варто згадати. А саме, оператори «>» та «<» необхідно екранувати за допомогою зворотної косої межі, інакше скрипт працюватиме неправильно, хоча повідомлень про помилки і не з'явиться. Скрипт інтерпретує знак ">" як команду перенаправлення виводу.

Ось як робота з цими операторами виглядає у коді:

#!/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

Ось результати роботи скрипту.

Bash-скрипти: початок
Порівняння рядків, виведене попередження

Скрипт, хоч і виконується, видає попередження:

./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

Тепер все працює як слід.

Bash-скрипти: початок
Порівняння рядків

Ще одна особливість операторів «>» та «<» полягає в тому, як вони працюють із символами у верхньому та нижньому регістрах. Для того, щоб зрозуміти цю особливість, підготуємо текстовий файл із таким вмістом:

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

Якщо його запустити, виявиться, що все навпаки - мала літера тепер більше великої.

Bash-скрипти: початок
Команда 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-скриптів і розглянули деякі базові речі. Насправді тема bash-програмування величезна. Ця стаття є перекладом першої частини великої серії із 11 матеріалів. Якщо ви хочете продовження прямо зараз - ось список оригіналів цих матеріалів. Для зручності сюди включений і той, переклад якого ви щойно прочитали.

  1. Bash Script Step By Step - Тут йдеться про те, як розпочати створення bash-скриптів, розглянуто використання змінних, описані умовні конструкції, обчислення, порівняння чисел, рядків, з'ясування відомостей про файли.
  2. Bash Scripting Part 2, Bash the awesome - Тут розкриваються особливості роботи з циклами for та while.
  3. Bash Scripting Part 3, Parameters & options — цей матеріал присвячений параметрам командного рядка та ключам, які можна передавати скриптам, роботі з даними, які користувач вводить, і які можна читати з файлів.
  4. Bash Scripting Part 4, Input & Output — тут йдеться про дескриптори файлів та про роботу з ними, про потоки введення, виведення, помилок, про перенаправлення виводу.
  5. Bash Scripting Part 5, Sighals & Jobs — цей матеріал присвячений сигналам Linux, їхній обробці в скриптах, запуску сценаріїв за розкладом.
  6. Bash Scripting Part 6, Functions — тут можна дізнатися про створення та використання функцій у скриптах, розробку бібліотек.
  7. Bash Scripting Part 7, За допомогою sed ця стаття присвячена роботі з потоковим текстовим редактором sed.
  8. Bash Scripting Part 8, Using awk — цей матеріал присвячений програмуванню мовою обробки даних awk.
  9. Bash Scripting Part 9, Regular Expressions - Тут можна почитати про використання регулярних виразів у bash-скриптах.
  10. Bash Scripting Part 10, Practical Examples — тут наведено прийоми роботи з повідомленнями, які можна надсилати користувачам, а також методика моніторингу диска.
  11. Bash Scripting Part 11, Expect Command - Цей матеріал присвячений засобу Expect, за допомогою якого можна автоматизувати взаємодію з інтерактивними утилітами. Зокрема, тут йдеться про expect-скрипти та про їхню взаємодію з bash-скриптами та іншими програмами.

Вважаємо, одна з цінних властивостей цієї серії статей полягає в тому, що вона, починаючи з найпростішого, придатного для користувачів будь-якого рівня, поступово веде до досить серйозних тем, даючи шанс усім бажаючим просунутися у створенні сценаріїв командного рядка Linux.

Шановні читачі! Просимо гуру bash-програмування розповісти про те, як вони дісталися вершин майстерності, поділитися секретами, а від тих, хто щойно написав свій перший скрипт, чекаємо на враження.

Bash-скрипти: початок

Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.

Перекладати інші частини циклу статей?

  • Так!

  • Ні не потрібно

Проголосували 1030 користувачів. Утрималися 106 користувачів.

Джерело: habr.com

Додати коментар або відгук