Використовуйте канали Linux, щоб створити хореографію того, як утиліти командного рядка співпрацюють. Спростіть складні процеси та підвищте свою продуктивність, використовуючи набір окремих команд і перетворюючи їх у єдину команду. Ми покажемо вам, як.
Труби всюди
Канали є однією з найкорисніших функцій командного рядка, які мають операційні системи Linux і Unix. Труби використовуються незліченною кількістю способів. Подивіться будь-яку статтю командного рядка Linux — на будь-якому веб-сайті, не тільки на нашому — і ви побачите, що канали з’являються частіше, ніж ні. Я переглянув деякі статті How-To Geek про Linux, і в усіх використовуються канали, так чи інакше.
Канали Linux дозволяють виконувати дії, які не підтримуються в готовому вигляді оболонка. Але оскільки філософія розробки Linux полягає в тому, щоб мати багато невеликих утиліт, які виконують своє виділена функція дуже добре, і без непотрібної функціональності — мантри «роби одну справу і зроби це добре» — ви можете звести рядки команд разом з каналами, щоб вихід однієї команди став входом іншої. Кожна команда, яку ви виконуєте, приносить команді свій унікальний талант, і незабаром ви виявите, що зібрали команду-переможець.
Простий приклад
Припустимо, що у нас є каталог, наповнений багатьма різними типами файлів. Ми хочемо знати, скільки файлів певного типу знаходиться в цьому каталозі. Є й інші способи зробити це, але метою цієї вправи є введення труб, тому ми збираємося зробити це з трубами.
Ми можемо легко отримати список файлів, використовуючи ls:
ls
Щоб виділити цікавий тип файлу, ми будемо використовувати grep. Ми хочемо знайти файли, у назві чи розширенні файлу яких є слово «сторінка».
Ми будемо використовувати спеціальний символ оболонки «|» щоб передати вихід з ls в grep.
ls | grep "page"
grep друкує рядки, які відповідати його шаблону пошуку. Таким чином, це дає нам список, що містить лише файли «.page».
Навіть цей тривіальний приклад демонструє функціональність труб. Висновок з ls не був надісланий у вікно терміналу. Він був надісланий до grep як дані для роботи з командою grep. Вихід, який ми бачимо, надходить від grep, яка є останньою командою в цьому ланцюжку.
Розширюємо наш ланцюг
Давайте почнемо розширювати наш ланцюжок команд із каналами. Ми можемо підрахувати файли «.page». додавши команду wc. Ми будемо використовувати параметр -l (кількість рядків) із wc. Зауважте, що ми також додали параметр -l (довгий формат) до ls . Незабаром ми скористаємося цим.
ls - | grep "page" | wc -l
grep більше не є останньою командою в ланцюжку, тому ми не бачимо її виведення. Вихід з grep подається в команду wc. Вихід, який ми бачимо у вікні терміналу, отримано від wc. wc повідомляє, що в каталозі є 69 файлів «.page».
Давайте ще раз продовжимо речі. Ми вилучимо команду wc з командного рядка і замінимо її на awk. У виводі ls є дев’ять стовпців з опцією -l (довгий формат). Ми будемо використовувати awk для друкувати колонки п’ять, три і дев’ять. Це розмір, власник та назва файлу.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}'
Ми отримуємо список цих стовпців для кожного з відповідних файлів.
Тепер ми передаємо цей вихід за допомогою команди sort. Ми будемо використовувати параметр -n (числовий), щоб повідомити сортування, яким має бути перший стовпець розглядаються як числа.
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n
Вихідні дані тепер відсортовано за розміром файлу з нашим індивідуальним вибором трьох стовпців.
Додавання іншої команди
Ми завершимо, додавши команду tail. Ми скажемо йому, щоб перерахувати останні п’ять рядків виводу тільки
ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5
Це означає, що наша команда перекладається як «покажи мені п’ять найбільших файлів «.page» у цьому каталозі, упорядкованих за розміром». Звичайно, для цього немає команди, але за допомогою каналів ми створили свої власні. Ми могли б додати цю — або будь-яку іншу довгу команду — як псевдонім або функцію оболонки, щоб зберегти весь введений текст.
Ось вихід:
Ми могли б змінити порядок розмірів, додавши параметр -r (зворотний) до команди сортування та використавши голову замість хвоста для виділення рядків від верхньої частини виходу.
Цього разу п’ять найбільших файлів «.page» перераховані від найбільшого до найменшого:
Деякі останні приклади
Ось два цікавих приклади з останніх статей про технічних спеціалістів.
Деякі команди, такі як xargscommand, розроблені щоб вхідні дані були передані до них. Ось як ми можемо запропонувати wc підрахувати слова, символи та рядки у кількох файлах, передаючи ls у xargs, який потім передає список імен файлів у wc, як ніби вони були передані wc як параметри командного рядка.
ls *.page | xargs wc
Загальна кількість слів, символів і рядків вказана в нижній частині вікна терміналу.
Ось спосіб отримати відсортований список унікальних розширень файлів у поточному каталозі з кількістю кожного типу.
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c
Тут багато чого відбувається.
ls: виводить список файлів у каталозі
обороти: Перевертає текст в іменах файлів.
вирізати: Обрізає струну при першому входженні вказаного роздільника «.». Текст після цього відкидається.
rev: повертає текст, що залишився, який є розширенням імені файлу.
сортування: сортує список за алфавітом.
uniq: підраховує кількість кожного унікальний запис у списку.
Результат показує список розширень файлів, відсортований за алфавітом із кількістю кожного унікального типу.
Іменовані труби
Нам доступний інший тип труб, які називаються трубами. Канали в попередніх прикладах створюються на льоту оболонкою, коли вона обробляє командний рядок. Труби створюються, використовуються, а потім викидаються. Вони швидкоплинні і не залишають слідів. Вони існують лише доти, доки виконується команда, яка їх використовує.
Іменовані канали відображаються як постійні об’єкти у файловій системі, тому ви можете побачити їх за допомогою ls. Вони стійкі, тому що витримають перезавантаження комп’ютера, хоча всі непрочитані дані в них на той момент будуть відкинуті.
Іменовані канали свого часу часто використовувалися, щоб дозволити різним процесам надсилати та отримувати дані, але я давно не бачив, щоб вони використовувалися таким чином. Безсумнівно, є люди, які все ще використовують їх з великим ефектом, але останнім часом я не стикався з ними. Але для повноти чи просто щоб задовольнити вашу цікавість, ось як їх можна використовувати.
Іменовані канали створюються за допомогою команди mkfifo. Ця команда створить іменований канал у поточному каталозі називається «geek-pipe».
mkfifo geek-pipe
Ми можемо побачити деталі названого каналу, якщо використаємо команду ls з параметром -l (довгий формат):
ls -l geek-pipe
Першим символом списку є «р», що означає канвелю. Якби це була «d», це означало б, що об’єкт файлової системи є каталогом, а тире «-» означало б, що це звичайний файл.
Використання Named Pipe
Скористаємося нашою трубою. Безіменні канали, які ми використовували в наших попередніх прикладах, передавали дані негайно від команди відправлення команді-отримувачу. Дані, надіслані через іменований канал, залишаться в каналі, доки не будуть прочитані. Дані фактично зберігаються в пам’яті, тому розмір названого каналу не буде змінюватися в списках ls незалежно від того, є в ньому дані чи ні.
Для цього прикладу ми будемо використовувати два вікна терміналу. Я буду використовувати етикетку:
# Terminal-1
в одному вікні терміналу і
# Terminal-2
в іншому, щоб ви могли розрізняти їх. Хеш «#» повідомляє оболонці, що далі є коментарем, і ігнорувати його.
Давайте розглянемо весь наш попередній приклад і перенаправимо його в названий канал. Отже, ми використовуємо і безіменний, і іменований канали в одній команді:
ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipe
Ми перенаправляємо вміст іменованого каналу в cat, щоб кіт відображав цей вміст у другому вікні терміналу. Ось результат:
І ви побачите, що вас повернули до командного рядка в першому вікні терміналу.
Отже, що щойно сталося.
Ми перенаправили деякий вихід в названий канал.
Перше вікно терміналу не повернулося до командного рядка.
Дані залишалися в каналі, поки не були зчитовані з каналу в другому терміналі.
Ми повернулися до командного рядка у першому вікні терміналу.
Можливо, ви думаєте, що можна запустити команду в першому вікні терміналу як фонове завдання, додавши & до кінця команди. І ти був би правий. У цьому випадку ми негайно були б повернуті до командного рядка.
Суть не використання фонової обробки полягала в тому, щоб підкреслити, що іменований канал є блокуючим процесом. Поміщення чогось у названу трубу відкриває лише один кінець труби. Інший кінець не відкривається, доки програма читання не витягне дані. Ядро призупиняє процес у першому вікні терміналу, поки дані не будуть прочитані з іншого кінця каналу.
Сила труб
У наш час іменовані труби є чимось новинкою.
З іншого боку, звичайні старі канали Linux є одним із найкорисніших інструментів, які ви можете мати у своєму наборі інструментів вікна терміналу. Командний рядок Linux починає оживати для вас, і ви отримуєте абсолютно новий потенціал, коли можете організувати набір команд, щоб створити єдину цілісну роботу.
Підказка про розставання: найкраще писати свої команди, додаючи по одній команді, і запустити цю частину, а потім додавати наступну команду.