Канали Linux відкривають нові горизонти у взаємодії командного рядка. Вони дозволяють вам створювати складні ланцюжки дій, об’єднуючи прості команди в ефективні робочі процеси. Цей підхід не тільки спрощує складні завдання, а й значно підвищує продуктивність. У цій статті ми розглянемо, як саме це працює.
Канали: Основа командного рядка
Канали є невід’ємною частиною операційних систем Linux та Unix, вони присутні практично в кожному посібнику або статті про командний рядок. Їх важливість важко переоцінити. Навіть при перегляді наших попередніх публікацій, ви неодмінно знайдете приклади їх використання.
Завдяки філософії Linux, яка полягає у створенні невеликих, спеціалізованих інструментів, кожен з яких виконує свою функцію на відмінно, канали дозволяють вам використовувати ці інструменти разом. Замість однієї складної команди, ви збираєте “команду мрії” з невеликих утиліт, де вихід однієї стає входом для іншої.
Простий приклад: Пошук файлів
Розглянемо приклад: ви хочете підрахувати, скільки файлів певного типу знаходиться у вашому каталозі. Хоча є декілька способів зробити це, ми використаємо канали, щоб продемонструвати їхню силу.
Першим кроком є отримання списку файлів за допомогою команди ls
:
ls
Далі, ми хочемо відфільтрувати файли, використовуючи grep
. Припустимо, нас цікавлять файли, у назві яких є слово “сторінка”.
Символ |
передає вихід команди ls
до grep
:
ls | grep "page"
Команда grep
виводить лише ті рядки, які відповідають заданому шаблону, залишаючи нам лише файли, що містять слово “page”.
У цьому простому прикладі ми бачимо, як вихід однієї команди (ls
) стає вхідними даними для іншої (grep
). Результат, який ми бачимо на екрані, є результатом роботи команди grep
.
Розширюємо наш ланцюжок
Тепер давайте додамо ще одну команду до нашого ланцюжка. Ми можемо підрахувати кількість файлів, додавши команду wc
з опцією -l
(кількість рядків). Для точності, додамо також опцію -l
(довгий формат) до ls
.
ls -l | grep "page" | wc -l
Тепер команда grep
не є останньою в ланцюжку, і ми бачимо результат роботи команди wc
, яка підраховує кількість файлів “сторінка” у каталозі (у цьому випадку 69).
Давайте замінимо wc
на awk
. Використовуючи awk
, ми можемо вивести стовпці 5, 3 і 9 з виводу команди ls -l
(розмір, власник і назву файлу):
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}'
Тепер ми бачимо список із трьох стовпців для кожного файлу “сторінка”.
Додамо сортування за розміром файлу:
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n
Тепер вихід відсортовано за розміром файлу.
Фільтрація результатів за допомогою tail
Наостанок, давайте виведемо лише останні 5 рядків, використовуючи команду tail -5
:
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5
Отже, команда тепер видає нам 5 найбільших файлів “.page” у каталозі, відсортованих за розміром. Ми створили власну команду, поєднуючи прості утиліти за допомогою каналів.
Ми можемо легко змінити порядок сортування, використовуючи sort -nr
, а також відобразити перші 5 рядків, використовуючи head -5
.
Додаткові приклади
Розглянемо ще декілька корисних прикладів. Наприклад, команда xargs
дозволяє передавати вихід інших команд як аргументи до іншої команди. Ось як можна підрахувати слова, символи та рядки у всіх файлах .page
:
ls *.page | xargs wc
Ось приклад отримання списку унікальних розширень файлів з кількістю кожного типу:
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c
Тут відбувається наступне:
ls
: виводить список файлів.
rev
: перевертає текст імен файлів.
cut
: обрізає текст по першому символу .
.
rev
: знову перевертає текст, отримуючи розширення файлу.
sort
: сортує список розширень.
uniq
: підраховує кількість кожного унікального розширення.
Результат: відсортований список розширень файлів з кількістю кожного.
Іменовані канали
Існує також інший тип каналів – іменовані канали. Звичайні канали створюються оболонкою під час виконання команди, існують лише під час її виконання. Іменовані канали є постійними об’єктами у файловій системі, вони можуть бути використані для взаємодії між різними процесами.
Іменовані канали можна створити за допомогою команди mkfifo
. Спробуємо створити канал під назвою “geek-pipe”:
mkfifo geek-pipe
Використовуючи команду ls -l
, ми можемо побачити, що це об’єкт файлової системи типу “p” (pipe):
ls -l geek-pipe
Використання іменованого каналу
На відміну від звичайних каналів, іменований канал утримує дані, поки вони не будуть прочитані. Для цього прикладу нам знадобиться два термінали.
# Terminal-1
в першому вікні термінала і
# Terminal-2
в другому.
В першому терміналі передамо результат команди в іменований канал:
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipe
Після виконання цієї команди дані відобразяться в другому терміналі.
І в першому терміналі ви знову побачите командний рядок.
Отже, ми:
Перенаправили вихід в іменований канал.
Перший термінал чекав на зчитування даних.
Дані були зчитані з іменованого каналу у другому терміналі.
Перший термінал знову отримав командний рядок.
Звичайно, можна запустити команду в першому терміналі у фоновому режимі (&
), але суть прикладу в тому, щоб підкреслити блокуючу природу іменованого каналу.
Сила каналів
Іменовані канали сьогодні використовуються рідко, натомість звичайні канали є невід’ємною частиною роботи у командному рядку Linux. Можливість об’єднувати прості команди в складні процеси відкриває нові можливості для автоматизації та оптимізації робочих процесів.
Порада наостанок: створюйте свої команди поступово, додаючи по одній команді за раз, перевіряючи результат на кожному етапі.