Цей контент є частиною серії: Використання UNIX
Слідкуйте за виходом нових статей цієї серії.
Однією з найрозумніших і потужних інновацій в UNIX є оболонка. Вона ефективніше, ніж графічний інтерфейс і дозволяє створювати сценарії для автоматизації багатьох завдань. Більш того, за допомогою конвеєра команд можна конструювати імпровізовані програми безпосередньо в командному рядку. Конвеєр збирає команди в ланцюжки, в яких стандартний висновок однієї команди стає стандартним вводом для наступної команди.
Часто використовувані скорочення
- GUI: Графічний інтерфейс користувача (Graphical user interface)
Але біля конвеєра є один серйозний недолік: він схожий на чорний ящик. Коли ви поєднуєте дві команди, єдиною ознакою ходу виконання процесу є висновок, що генерується останньої в послідовності командою. Можна вставити в послідовність команду tee. а також спостерігати за ростом вихідного файлу за допомогою tail. але ці рішення відмінно працюють тільки при одноразовому застосуванні в команді, в іншому випадку стандартні потоки виведення (stdout) і стандартні потоки помилок (stderr) різних фаз перемішуються. До того ж обидва ці рішення є грубими індикаторами, які, ймовірно, не покажуть, скільки насправді обчислень потрібно на кожному кроці.
Звичайно, можна розбити складну послідовність команд на безліч окремих кроків, кожен з яких буде генерувати свій власний вихідний файл. Справді, якщо ви хочете перевіряти результат роботи на кожному інтервалі, декомпозиція є ідеальним рішенням. Створіть сценарій, в якому на кожному кроці генеруйте окремий файл з даними і використовуйте його в якості вхідних даних для наступного кроку і т.д. В результаті ви отримаєте файл з підсумковими результатами. Однак така практика погано підходить до імпровізаційної природі командного рядка.
Те, що нам потрібно - це індикатор прогресу виконання завдання, який можна вбудовувати в командний рядок для вимірювання швидкості передачі даних. В ідеалі добре було б використовувати цей індикатор повторно, щоб порівнювати продуктивність на кожному кроці. Ну і, оскільки немає межі досконалості, добре б, щоб це був інструмент з відкритим кодом, який би працював з різними варіантами UNIX, такими як Linux® і Mac OS X.
Всім нашим побажанням задовольняє програма Pipe Viewer (pv), написана системним адміністратором Ендрю Вудом (Andrew Wood) і поліпшується протягом останніх чотирьох років багатьма іншими розробниками. Вона дозволяє заглянути всередину "трубопроводу" командного рядка. Як йдеться на домашній сторінці проекту. pv "можна вставляти в конвеєр між двома процесами для отримання візуальної індикації того, як швидко передаються між ними дані, як багато часу пройшло і наскільки близько завершення роботи". Зауважимо, що для вимірювання відносної продуктивності можна використовувати pv кілька разів в одній послідовності команд.
У цій статті розповідається про те, як зібрати pv для своєї UNIX-системи і застосовувати її для простих і складних комбінацій інструментів командного рядка. Давайте почнемо з огляду того, як процеси обмінюються один з одним даними за допомогою конвеєрів.
Конвеєри UNIX: трубопровід для процесів
На малюнку 1 показані етапи створення конвеєра, що з'єднує два незалежних процесу.
Малюнок 1. Створення конвеєра, що з'єднує два процеси
На початку, на фазі 1, процес-ініціатор читає дані з stdin. виводить результат в stdout. а помилки в stderr. stdin. stdout і stderr є файловими дескрипторами. Кожна операція, яка виконується з файловим дескриптором, наприклад open. read. write. rewind. truncate або close. змінює стан файлу.
Потім в фазі 2 процес-ініціатор створює конвеєр. Конвеєр складається з черги і двох файлових дескрипторів. Один потрібен, щоб поміщати дані в чергу, інший - щоб витягати їх з черги. Конвеєр являє собою структуру даних типу FIFO (першим прийшов - першим вийшов).
Сам по собі конвеєр мало корисний; він призначений для того, щоб з'єднувати процес-постачальник і процес-споживач (даних). Тому процес-ініціатор в фазі 3 ответвляет або створює собі процес, з яким буде працювати в парі.
Фази 1-4 ілюструють те, як оболонка з'єднує за допомогою конвеєра (|) дві утиліти одну з іншого в командному рядку. Зауважимо тільки, що оболонка створює для кожної утиліти новий процес, а сама займається управлінням ходом роботи.
Наприклад, на малюнку 2 показано, як можна за допомогою конвеєрів з'єднати команди find. grep і wc. щоб знайти і підрахувати кількість файлів, імена яких починаються з літери a в нижньому регістрі. Оболонка залишається незалежною; висновок find служить вхідним потоком для grep. результат роботи якого в свою чергу направляється команді wc. wc обробляє отримані від grep дані і виводить результат своєї роботи в stdout. Зазвичай оболонка виводить stdout на термінал, але його також можна перенаправити в файл.
Малюнок 2. З'єднуємо команди за допомогою конвеєрів
Якщо ви хочете вивчити роботу двох UNIX-процесів, створіть два конвеєра і перевизначите файлові дескриптори процесів так, щоб вони були один для одного і постачальником і споживачем даних. На малюнку 3 показаний обмін даними між процесами, в якому для обох процесів перевизначаються потоки stdin і stdout.
Малюнок 3. Досліджуємо два UNIX-процесу
Ми зробили короткий огляд конвеєрів, тепер давайте познайомимося ближче з утилітою Pipe Viewer.
Pipe Viewer: примітний конвеєр
Pipe Viewer - це додаток з відкритим вихідним кодом. Можна завантажити його код і зібрати додаток з нуля або завантажити виконуваний файл програми зі сховищ вашого дистрибутива UNIX, якщо він там є.
Лістинг 1. Код установки Pipe Viewer
Щоб завантажити виконуваний файл програми pv зі сховищ, знайдіть за допомогою менеджера пакетів свого дистрибутива наявні пакети за словами pv або pipe viewer. Наприклад в Ubuntu 9 пошук за допомогою менеджера пакетів APT дає наступний результат:
Завантажити та встановити пакет за допомогою свого менеджера пакетів. В Ubuntu це робиться командою apt-get install.
Тепер давайте випробуємо pv в дії. У найпростішому варіанті використання pv може замінювати традиційну утиліту cat для передачі байтів іншій програмі і вимірювання загальної продуктивності. Наприклад, можна використовувати pv для відстеження тривалої операції стиснення:
При запуску pv відображає індикатор прогресу, який показує і безперервно оновлює різні показники ходу виконання роботи. Зазвичай pv зліва направо відображає кількість оброблених даних, минулий час, продуктивність в мегабайтах в секунду, а також візуальне і чисельне представлення кількості виконаної роботи і оцінки часу, що залишився. У наведеному вище прикладі оброблено 96.1МБ з 109МБ, і на решту 13% файлу буде потрібно приблизно 9 секунд
За замовчуванням pv відображає всі індикатори стану, значення яких він може обчислити. Наприклад, якщо вхідні дані pv не є файлом, і не вказано вручну точного розміру, індикатор прогресу переміщається зліва направо, щоб відображати активність програми, але pv не зможе визначити відсоток виконаної роботи. наприклад:
У цьому прикладі на віддаленій машині виконується команда tar. результат роботи якої відправляється на локальну систему в файл projectx.tar. Оскільки pv не може обчислити загальну кількість байтів, які будуть передані, він показує продуктивність, що минув, і спеціальний індикатор, що відображає активність програми. Він являє собою маленький індикатор ( <=> ), Який переміщається зліва направо по мірі передачі даних.
Параметр --wait відкладає відображення індикатора прогресу до моменту фактичного отримання першого байта. Тут --wait корисний, так як команда ssh може запропонувати ввести пароль.
Можна включати індикатори на свій розсуд, вказуючи прапори з промовистими іменами:
У цій команді за допомогою прапора --bytes включається відображення кількості переданих байтів. Також є параметри --progress. --timer. --eta. --rate і --numeric. Якщо ви вказуєте один або більше з цих параметрів, всі залишилися (не вказані) індикатори автоматично вимикаються.
Є ще одне просте застосування pv. Параметр --rate-limit може обмежувати пропускну здатність. Цей параметр приймає в якості аргументів число і суфікс, що позначає одиницю виміру. Наприклад, m позначає число мегабайтів в секунду:
Попередня команда вимикає всі індикатори (--quiet) і обмежує пропускну здатність швидкістю 1 МБ / с.
Більш складне використання Pipe Viewer
До сих пір в наших прикладах використовувався тільки один екземпляр Pipe Viewer, який виступав в ролі постачальника або споживача даних в парі команд. Однак можливі і більш складні комбінації. Дотримуючись деяких умови, можна використовувати кілька примірників pv в одній командному рядку. А саме: необхідно за допомогою параметра --name вказати ім'я кожного примірника pv і включити багатостроковий режим за допомогою параметра --cursor. Разом ці два параметри створюють серію іменованих індикаторів, по одному індикатору на екземпляр (програми).
Наприклад, ми хочемо відстежувати одночасно і окремо процеси передачі даних і їх стиснення. Ми призначаємо один екземпляр pv першої операції, і ще один - другий:
Після введення пароля ми побачимо, що Pipe Viewer показує двухстрочний індикатор активності:
Перший рядок з написом ssh показує прогрес передачі даних. Другий рядок з написом gzip показує прогрес стиснення даних. Оскільки жодна з команд не може визначити обсяг даних в своїй операції, на кожному рядку показаний обсяг переданих даних і індикатор активності.
Якщо ви знаєте, або можете оцінити або обчислити об'єм даних, які обробляються операцією, то можна використовувати параметр --size. Додавши цей параметр, ви отримаєте більш детальну інформацію в індикаторах прогресу.
Наприклад, якщо ми хочемо відстежувати прогрес великого завдання архівування, то можна використовувати інші утиліти UNIX, щоб оцінити загальний розмір вихідних файлів. Утиліта df може показувати статистику для цілої файлової системи, а du може обчислити розмір ієрархії файлів довільної глибини:
Тут послідовність команд du -sh work | cut -f1 видає загальний розмір робочої директорії в форматі, сумісному з pv. Команда du -h генерує дані в легкому для читання форматі, наприклад 17M для 17 мегабайт, який підходить для використання з pv. (Команди ls і df також підтримують параметр -h для виведення даних в зрозумілому людині форматі). Так як тепер pv очікує, що через конвеєр буде передано певну кількість байтів, він відображає повноцінний індикатор прогресу:
І нарешті, є ще один прийом, який напевно буде вам корисний. Крім підрахунку байтів, Pipe Viewer може візуалізувати прогрес операції, підраховуючи рядки даних. Якщо вказати модифікатор --line-mode. то pv оновлює індикатор прогресу кожен раз при зустрічі нового рядка. Також можна вказати параметр --size. тоді число буде інтерпретовано як очікувана кількість рядків.
Розглянемо приклад. Команда find часто буває корисною, коли потрібно знайти голку в стозі сіна, наприклад, щоб відшукати всі місця, де у великій кількості коду використовується певний системний виклик. У таких випадках можна скористатися подібною командою:
Цей код знаходить всі файли вихідного коду на C і повертає імена файлів, в яких зустрічається рядок fopen. Результат роботи направляється в файл з ім'ям results. Для відображення активності додамо команду pv.
Строковий режим феноменальний, тому що багато команд UNIX, наприклад find. оперують метаданими файлів, а не їх вмістом. Строковий режим ідеально підходить для сценаріїв системного адміністрування, які копіюють або стискають велику кількість файлів.
Загалом, Pipe Viewer можна вставляти в командному рядку і сценаріях всюди, де можна виміряти швидкість передачі даних. Іноді потрібно бути винахідливим - наприклад, щоб виміряти швидкість копіювання директорії, можна перейти від cp -pr до tar.
Також строковий режим можна використовувати при роботі з мережевими утилітами, такими як wget. curl і scp. Наприклад, можна використовувати pv для відображення виконання процесу передачі відомого обсягу даних на віддалену машину. І, оскільки багато мережеві утиліти можуть зчитувати вхідні дані з файлу, можна використовувати розмір такого файлу в якості аргументу для параметра --size.
маленька коштовність
Pipe Viewer - це одна з тих маловідомих перлин, без яких, познайомившись з ними одного разу, вже неможливо обходитися. Можливо, ви знайдете кілька способів застосування pv в повсякденній роботі в командному рядку, але, швидше за все, ви знайдете безліч варіантів її використання в сценаріях автоматизації. Замість того щоб, втупившись в мерехтливий курсор, терпляче очікувати будь-якого сигналу про те, що все йде добре, можна поставити датчик для отримання відомостей про роботу програми в реальному часі. Pipe Viewer дозволяє почути биття серця вашої машини.
Ресурси для скачування
Схожі теми
- Speaking UNIX: Peering into pipes - оригінал статті (EN).
- Дізнайтеся більше про оболонках UNIX. (EN)
- На сайті developerWorks в розділі AIX і UNIX ви завжди зможете знайти величезну кількість довідкових матеріалів, що стосуються всіх аспектів адміністрування систем AIX. (EN)
- Дізнайтеся більше інформації про Pipe Viewer і завантажте його. (EN)