Professional Documents
Culture Documents
Конспект По Bash - Codeguida
Конспект По Bash - Codeguida
2017 Конспект по Bash Codeguida
Якщо ви працюєте в ІТ, то як ніхто знаєте про ціну часу. Оптимізація робочого
процесу один з найважливіших аспектів роботи в ІТ. Так чи інакше, наша
робота (будь то верстка сайту, написання модулів, чи тестування додатків)
вимагає повторення одних і тих самих дій: швидкі скріншоти з завантаженням
на сервер, обробка виділеного тексту, конвертація файлів, парсинг даних та
багато іншого. Аби не робити зайвих дій, а сконцентруватись на ідеї та самій
суті її реалізації, ще в 1978 році Стівен Борн розробив командну оболонку [sh]
[wikish], яка згодом, в 1987 році була вдосконалена Браяном Фоксом і
переросла в те, що ми знаємо сьогодні як [bash][wikibash] (Bourne again shell).
Цілком логічно, що з’являється запитання: "Для чого мені потрібне щось, що
написали майже півстоліття тому?" Так от відповідь на нього проста: це "щось"
дотепер є найпотужнішим інструментом автоматизації та, дефакто,
стандартом для написання простих, але ефективних сценаріїв на всіх unix
based системах. Саме тому знати загальний синтаксис bash та вміти писати на
ньому критичний скіл для розробника.
В цьому пості я опишу синтаксичні конструкції, наведу приклади простих
сценаріїв та вкажу на деякі підводні камені в bash. Впевнений, що такий
конспект обов’язково стане в нагоді як початківцям, так і досвідченим
розробникам, які могли забути деякі особливості цієї надпотужної командної
оболонки.
Оболонки та виклик сценаріїв
Користувацька оболонка bash може працювати в двох режимах
інтерактивному та, відповідно, неінтерактивному. Відкрити оболонку в Ubuntu
можна комбінацією клавіш Ctrl + Alt + F1 , звичний графічний інтерфейс
зникне, а перед вами відкриється один з семи віртуальних терміналів,
доступних в дистрибутиві Ubuntu. Якщо оболонка видає запрошення (щось на
зразок того, яке можна побачити нижче), то ви працюєте в інтерактивному
режимі:
https://codeguida.com/post/270 1/16
03.07.2017 Конспект по Bash Codeguida
user@host:~$
Тут можна вводити найрізноманітніші unixкоманди (як
от: ls, grep, cd, mkdir, rm) і бачити результат їх виконання. Інтерактивною ця
оболонка називається тому, що вона взаємодіє з користувачем напряму.
Оточення робочого столу (графічний інтерфейс), в сімействі систем Debian (до
яких належить і Ubuntu), прийнято розміщувати в сьомому віртуальному
терміналі, тому щоб повернутись до звичного оточення робочого столу
наберіть комбінацію Ctrl + Alt + F7 .
Звісно працювати в віртуальних терміналах не надто зручно, особливо, якщо
потрібно редагувати документ та водночас виконувати якінебудь команди,
тому надалі ми користуватимемось вбудованим в графічний інтерфейс
емулятором віртуального терміналу, вбудованим в Ubuntu. Відкрити його
можна комбінацією клавіш Ctrl + Alt + T , або з Unity Dash, знайшовши його
в списку програм.
В неінтерактивному режимі оболонка читає команди з деякого файлу і
послідовно виконує їх. Коли інтерпретатор дійде до кінця файлу, робота з
оболонкою автоматично завершиться. Запустити оболонку в
неінтерактивному режимі можна з допомогою команд:
sh скрипт
bash скрипт
https://codeguida.com/post/270 2/16
03.07.2017 Конспект по Bash Codeguida
chmod +x скрипт
Окрім цього, в першому рядку скрипта необхідно вказати яка оболонка
повинна виконувати цей сценарій. Це можна зробити, розмістивши на початку
відповідну вказівку #!/bin/sh (для оболонки sh) або #!/bin/bash (відповідно
для bash). Після цього файл можна буде викликати на виконання звернувшись
до нього в терміналі:
./скрипт
Коментарі
Сценарії можуть містити коментарі. Коментарі це оператори, які можна
розміщувати в сценарії оболонки, але який ігнорується при виконанні.
Коментарі повинні починатись з символу # і продовжуються до символу
нового рядка.Наприклад:
#!/bin/bash
# Сценарій, що виведе ім’я користувача
whoami
Змінні
Оболонка дозволяє створювати та видаляти змінні, а також виконувати над
ними операції. Змінні в bash можуть знаходитись в 3х областях видимості:
Локальні змінні це звичайні змінні в всередині одного сценарію. Вони не
доступні іншим програмам та сценаріям, які запускаються з цієї оболонки.
Оголошуються змінні з допомогою символу = (зверніть увагу на те, що перед
https://codeguida.com/post/270 3/16
03.07.2017 Конспект по Bash Codeguida
і після = немає пробілів), а до їх значення звертаються з допомогою
символу $ :
name="Петро Петрович"
echo $name # вивід значення
unset name # видалення змінної
Також можна оголосити локальну змінну всередині функції і яка буде доступна
лише в тілі цієї функції:
local локальна_змінна=значення
Змінні оточення це змінні, які доступні будьяким програмам, що запущені з
данної оболонки. Оголошуються вони так само як і локальні змінні, але з
командою export :
export глобальна_змінна=значення
В bash є багато змінних оточення, які досить часто зустрічаються в сценаріях,
наприклад:
HOME шлях до домашнього каталогу користувача;
PATH список каталогів, в яких оболонка шукає виконувані файли;
PWD шлях до робочого каталогу;
RANDOM формує ціле випадкове число;
HOSTNAME ім’я комп’ютера, на якому виконується оболонка;
Детальніше про змінні оточення можна почитати [тут][envvars].
https://codeguida.com/post/270 4/16
03.07.2017 Конспект по Bash Codeguida
Змінні оболонки це змінні, які встановлюються оболонкою і необхідні їй для
коректної роботи. Ці змінні мають імена порядкового номера ( $1 , $2 , $3 ,
...) і містять аргументи, які передавались сценарію при запуску, як от:
./some_script.sh VAL1 VAL2 # всередині сценарію $1='VAL1', $2='VAL2'
Змінним можна присвоювати значення за замовчуванням таким чином:
: ${VAR:='значення за замовчуванням'} # Якщо змінна VAR порожня, присвоїти
їй "значення за замовчуванням"
Масиви та списки
В bash також є можливість працювати з масивами. При роботі з масивами
часто користуються змінною оточення IFS роздільника полів для вхідних
рядків (IFS Input Field Separator). За замовчуванням IFS рівний пробільному
символу, але може бути змінений для розбиття рядка на елементи масиву,
наприклад, за комами. Зверніть увагу, що для формування змінних оболонки,
які доступні через $1 , $2 і т.д., використовується саме змінна IFS, тобто
введений після ім’я скрипта рядок аргументів, буде розділений саме за
першим символом, який зберігається в цій змінній.
Оголосити масив можна наступним чином:
files[0]=Яблуко
files[1]=Груша
echo ${files[*]} # надрукує елементи масиву без врахування IFS
echo ${files[@]} # надрукує елементи масиву з IFS в якості розільника
https://codeguida.com/post/270 5/16
03.07.2017 Конспект по Bash Codeguida
Отримувати доступ до елементу масиву можна з
допомогою зрізів: ${arr:0:1} . Видалити перший елемент масиву можна з
допомогою зсуву: shift arr . Додати в елементи в масив: arr=("${arr[@]}"
"Item 1" "Item 2") . Перевірити входження елементу в масив реалізується з
допомогою дещо складнішої конструкції:
if [[ ${arr[(r)some]} == some ]]; then
# команди, якщо елемент входить
else
# команди, якщо не входить
fi
Підставлення результатів операцій
Присвоїти змінній результат роботи команди чи арифметичних операцый
можна з допомогою апострофів, або конструкції $(вираз) :
now=`data +%T`
# або
now=$(data +%T)
echo now # 19:08:26
Арифметичні операції необхідно огортати в подвійні дужки:
foo=$(( ((10 + 5*3) – 7) / 2 ))
echo $foo #> 9
https://codeguida.com/post/270 6/16
03.07.2017 Конспект по Bash Codeguida
З допомогою фігурних дужок можна генерувати рядки довільного вигляду, або
враховувати різні варіанти написання слова:
echo beg{i,a,u}n #> begin began begun
Варто згадати і про строгість лапок в bash: одинарні лапки строгі, подвійні
нестрогі. Це означає, що при підстановленні змінних в рядок з подвійними
лапками, інтерпретатор підставить відповідне значення змінної. Одинарні
лапки виведуть рядок так, як ви його написали. Приклад:
echo "Домашня директорія: $HOME" #> Домашня директорія: /home/user
echo 'Домашня директорія: $HOME' #> Домашня директорія: $HOME
Потоки
Файл з якого відбувається читання, називають стандартним потоком
введення, а в який відбувається запис, відповідно стандартним потоком
виводу. В bash є три стандартних потоки:
0 stdin ввід
1 stdout вивід
2 stderr потік помилок
Для перенаправлення потоків використовують основні оператори:
> перенаправлення потоку виведення в файл (файл буде створений,
або перезаписаний);
>> дописати потік виведення в кінець файлу;
< перенаправляє данні з файлу в потік введення;
https://codeguida.com/post/270 7/16
03.07.2017 Конспект по Bash Codeguida
<<< читання даних з рядка, замість всього вмісту файлу (працює
для bash 3+);
2> перенаправляє потік помилок в файл (файл буде створений, або
перезаписаний);
2>> дописати помилки в кінець файлу; тадада
Канали
Стандартні потоки можна перенаправляти не лише в файли, але й на вхід
інших сценаріям. З’єднання потоку виведення одної програми з потоком
введення іншої називають каналом або пайпом (pipe). Нижче наведений
простий конвеєр з трьох команд: команда1 перенаправляє свій вивід на
вхід команді2 , яка, в свою чергу, перенаправляє власний вивід на
вхід команді3 :
cmd1 | cmd2 | cmd3
Конвеєри
Конвеєри це команди, що з’єднані операторами ; , && , || для
виконання в певній послідовності. Оператори організації конвеєрів працюють
наступним чином:
https://codeguida.com/post/270 8/16
03.07.2017 Конспект по Bash Codeguida
Умовні оператори
В скриптовій мові bash підтримуються два оператори
розгалуження: if та case . Оператор if , як і в інших мовах, виконує
певний блок вказівок, в залежності від умови. Умову огортають в подвійні
квадратні дужки [[ ... ]] , які bash розглядає як один елемент з кодом
виходу. Всередині блоку операторів огорнутого в [[ ]] дозволяється
використовувати оператори && та || . Приклади:
# Однорядковий запис
if [ ... ]; then echo "true"; else echo "false"; fi;
## Вкладені умови
if [ ... ] && [ ... ]; then
...
elif [[ ... && ... ]]; then
...
else
...
fi;
В нижче наведена таблиця з можливими умовами порівняння:
# Робота з файлами
‐e Перевірити чи існує файл чи директорія (‐f, ‐d)
‐f Файл існує (!‐f ‐ не існує)
‐d Каталог існує (!‐f ‐ не існує)
‐s Файл існує і він не порожній
‐r Файл існує і доступний для читання
‐w ... на запис
‐x ... на виконання
‐h Є символічним посиланням
# Робота з рядками
‐z Порожній рядок
https://codeguida.com/post/270 9/16
03.07.2017 Конспект по Bash Codeguida
‐n Не порожній рядок
== Рівне
!= Не рівне
# Операції з числами
‐eq Рівне
‐ne Не рівне
‐lt Менше
‐le Менше або рівне
‐gt Більше
‐ge Більше або рівне
Приклади:
if [ `uname` == "Adam"]; then
echo "Не їж яблуко!"
elif [ `uname` == "Eva"] then
echo "Не бери яблуко!"
else
echo "Яблука зараз дуже дорогі!"
fi;
Якщо необхідно зробити вибір з кількох альтернатив, в нагоді стане
оператор case . Принцип його роботи найлегше зрозуміти на прикладі:
case "$extension" in
(jpg|jpeg)
echo "Це зображення у форматі jpeg."
;;
png)
echо "Це зображення у форматі png"
;;
gif)
echo "А це гіфочка))"
*)
echo "Оу! Це взагалі не зображення!"
;;
esac
https://codeguida.com/post/270 10/16
03.07.2017 Конспект по Bash Codeguida
Цикли
Мова оболонки дає користувачеві можливість організовувати циклічне
виконання інструкцій з допомогою циклів:
while
for
select
while умовa do
тіло
done
#!/bin/sh
# Квадрати чисел від 1 до 10
x=0
while [ $x –lt 10 ] do #значення змінної x менше 10?
echo $(($x*$x))
x=`expr $x + 1` # збільшуємо х на 1
done
https://codeguida.com/post/270 11/16
03.07.2017 Конспект по Bash Codeguida
for ім’я in елемент1 елемент2 ... елементN do
тіло
done
В якості елементів зазвичай використовують різноманітні шаблони (wildcards).
Дуже зручно застосовувати for для проходження по каталогах та виконання
операцій над групою файлів. В прикладі нижче, цикл проходить по всіх файлах
з розширенням *.bash , переміщує їх в директорію ~/scripts та додає їх
права на виконання.
#!/bin/sh
# Переміщення всіх скриптів з ~ в директорію ~/scripts
for FILE in $HOME/*.bash do
mv $FILE ${HOME}/scripts
chmod +x ${HOME}/scripts/${FILE}
done
select відповідь in елемент1 елемент2 ... елементN do
тіло
done
При виконанні цього оператору, всі елементи зі списку висвічуються на екрані
зі своїми порядковими номерами у вигляді списку варіантів відповіді, після
списку виводиться спеціальне запрошення для введення. Зазвичай воно має
вигляд #? . Введений користувачем номер списку записується в
https://codeguida.com/post/270 12/16
03.07.2017 Конспект по Bash Codeguida
#!/bin/sh
echo ‐n "Введіть назву пакету: " && read PACKAGE
PS3="Оберіть пакетний менеджер : "
select ITEM in bower, npm, pip do
case $ITEM in
bower) bower install $PACKAGE ;;
npm) npm install $PACKAGE ;;
pip) pip install $PACKAGE ;;
esac
break
done
Приклад вище запитує в користувача назву пакету, який він бажає встановити,
далі цікавиться який пакетний менеджер використати і в залежності від вибору
встановлює потрібний пакет та зупиняє виконання.
Оболонка також має команди, для зміни нормального виконання циклу.
Оператор break повністю зупиняє виконання циклу, оператор continue
переходить до наступної ітерації.
Функції
В сценаріях оболонки можливе оголошення та виклик функцій. Варто
зазначити, що саме поняття функцій в bash дещо урізане. Насправді, функції в
bash це іменована група команд, які виконаються під час звертання до
функції. В будьякому випадку функціями слід користуватись всюди, де є код,
що повторюється з невеликими варіаціями.
https://codeguida.com/post/270 13/16
03.07.2017 Конспект по Bash Codeguida
Оголошення функції має такий вигляд:
ім’я_функції () {
команди
}
ім’я_функції # звертання до функції
Оголошення функції обов’язково повинне передувати її першому виклику.
Звертання до функції відбувається шляхом вказання її імені в якості команди.
Функція може приймати аргументи та повертати після свого виконання
результат код виходу. Функція посилається до своїх аргументів точно так
само, як і до локальних змінних, з допомогою позиційних змінних $1 , $2 і
тд. Результат роботи можна повертати з допомогою команди return .
Наприклад, функція, яка приймає параметр (ім’я) і завершуючи свою роботу з
кодом 0:
#!/bin/sh
#функція з параметром
greeting() {
if [ ‐n "$1" ]; then
echo "Привіт, $1!"
else
echo "Привіт, невідомий!"
fi
return 0
}
greeting користувач #> Привіт, користувач!
greeting #> Привіт, невідомий!
програма завершилась помилкою, кодом завершення буде ціле число
відмінне від нуля. Зверніть увагу, що якщо сценарій завершується
командою exit без параметрів, кодом завершення сценарію буде код
завершення останньої виконаної команди.
Налагодження сценаріїв
Оболонка дає кілька засобів для налагодження сценаріїв. Для активації
режиму налагодження, сценарій повинен бути запущений з допомогою
спеціальних опцій. Перший рядок сценарію повинен мати вигляд:
#!/bin/sh опция
Можна обирати серед таких опцій:
–n читати всі команди, але не виконувати їх;
–v виводити всі рядки по мірі їх обробки інтерпретатором;
–x виводити всі команди та їх аргументи по мірі їх виконання.
Для налагодження сценарію частинами, потрібний фрагмент помічають
викликом команди set iз відповідною опцією з таблиці. При чому, для
увімкнення режиму налагодження, перед опцією вказують символ ‐ , для
вимкнення режиму налагодження використовують + :
set –x # вмиваємо режим налагоджування
...
set +x # вимикаємо режим налагоджування
Загальна практика налагоджування полягає в тому, щоб перш ніж запустити
його на виконання, необхідно перевірити його синтаксис з допомогою опції ‐
https://codeguida.com/post/270 15/16
03.07.2017 Конспект по Bash Codeguida
Післямова
Сподіваюсь ви знайшли для себе щось нове в цьому конспекті, або,
принаймні, освіжили свої знання.
Якщо вас зацікавив скриптинг на Bash, прошу підтримати мене, поширюючи
статтю серед своїх друзів.
Радий буду почути конструктивну критику та зауваження в коментарях.
https://codeguida.com/post/270 16/16