Процесне заміщення

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

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

Історія

[ред. | ред. код]

Процесне заміщення було доступне для вибору при компіляції в ksh88, KornShell[1] версії 1988 року. RC оболонка подає цю можливість як “розгалуження конвеєру” в  Version 10 Unix, випущеній в 1990 році.[2]  Bash shell запропонував таку можливість в версії 1.14 1994 року.[3]

Приклади

[ред. | ред. код]

Наступні приклади використовують KornShell синаксис.

Команда diff в Unix зазвичай приймає назви двох файлів, які треба порівняти, або один файл і стандатний ввід. Процесне заміщення дозволяє порівнювати вивід двох програм напряму:

$ diff <(sort file1) <(sort file2)

Вираз <(command) вказує командному інтерпретатору виконати command і вивести вихідні дані файлом. Command може бути будь-якою командою оболонки довільної складності.

Альтернатива цьому, не використовуючи заміщення, виглядає наступним чином:

  1. Зберегти вивід команди в тимчасовий файл, тоді його зчитати
    $ sort file2 > /tmp/file2.sorted
    $ sort file1 | diff - /tmp/file2.sorted
    $ rm /tmp/file2.sorted
    
  2. Створити іменований канал (також відомий як FIFO)), розпочати одну команду, що вводить в нього дані, у фоновому режимі, тоді виконати іншу команду, вхідними даними для якої слугуватиме цей іменований канал.
    $ mkfifo /tmp/sort2.fifo
    $ sort file2 > /tmp/sort2.fifo &
    $ sort file1 | diff - /tmp/sort2.fifo
    $ rm /tmp/sort2.fifo
    


Обидві альтернативи є більш громіздкими. процесне заміщення можна також використовувати, щоб захопити вивід, який типово записувався би у файл, і перенаправити його на ввід іншому процесу. У оболонці Bash синтаксисом для запису в процес є >(команда). Ось приклад використання tee, wc та gzip команд, що рахують кількість стрічок у файлі командою wc -lі стискає командою gzip одним рядком:

$ tee >(wc -l >&2) < bigfile | gzip > bigfile.gz

Переваги

[ред. | ред. код]

Основні переваги процесного заміщення над його альтернативою є:

  • Простота: команди можна передавати вбудовано, немає потреби зберігати тимчасові файли і заздалегідь створювати іменовані канали.
  • Продуктивність: читання безпосередньо з іншого процесу є часто швидшим, ніж запис тимчасового файлу на диск, а тоді зчитування його в потік наново.Це також економить пам’ять диску.
  • Паралелізм: заміщений процес може виконуватись паралельно з командою, яка читає його вивід і передає дані на ввід, користуючись перевагами мультипроцесорності для зменшення загального часу компіляції.

Механізм роботи

[ред. | ред. код]

Під капотом процесне заміщення має два шляхи виконання. В системах, що підтримують /dev/fd (тобто більшість Unix-подібних систем) воно виконує системний виклик pipe(), який повертає файловий дескриптор $fd для неіменованого каналу, тоді створює рядок /dev/fd/$fd і заміщує нею дані в командному рядку. В системах, де така директорія не підтримується, воно викликає mkfifo з новою тимчасовою назвою файлу для створення іменованого каналу і заміщує дані в командному рядку цією назвою файлу. Для наочного прикладу наведених кроків, перегляньмо наступний приклад командного заміщення в системі, що підтримує/dev/fd

$ diff file1 <(sort file2)

Кроки, що виконує оболонка:

  1. Створити новий неіменований канал. До нього можна доступитися за /dev/fd/63 або схожим шляхом. Перевірити можна командоюecho <(true).
  2. Виконати командне заміщення у фоновому режимі (в даному випадку це командаsort file2), направивши його вивід в неіменований канал.
  3. Виконати основну команду, замінюючи потрібну команду шляхом до неіменованого каналу. В цьому випадку повний вигляд команди буде приблизно наступним: diff file1 /dev/fd/63.
  4. Коли виконання завершено, закрити неіменований канал.

Для іменованих каналів виконання відрізняється лише створенням на видаленням каналу: mkfifo для створення та  unlink для видалення. Усі інші аспекти залишаються незмінними

Обмеження

[ред. | ред. код]

Створенні “файли” не відслідковуються, тобто процес, що виконує читання та запис до файлу не має безпосереднього доступу до нього, він повинен зчитати чи записати файл від початку до кінця з першого разу. Програми, що явно перевіряють тип файлу перед  його відкриттям, можуть не працювати з процесним заміщенням, тому що “файл”, який є результатом процесного заміщення не є звичайним файлом. До того ж, аж до Bash 4.4 (2016 року випуску) отримати код виходу з програми, створений самою оболонкою, було неможливо.[4]

Див. також

[ред. | ред. код]

Посилання

[ред. | ред. код]
  1. Rosenblatt, Bill; Robbins, Arnold (April 2002). Appendix A.2. Learning the Korn Shell (вид. 2nd). O'Reilly & Associates. ISBN 0-596-00195-9.
  2. Duff, Tom (1990). Rc — A Shell for Plan 9 and UNIX Systems. CiteSeerX 10.1.1.41.3287.
  3. Ramey, Chet (18 серпня 1994). Bash 1.14 release notes. Free Software Foundation. Available in the  Gnu source archive of version 1.14.7 [Архівовано 4 березня 2016 у Wayback Machine.] as of 12 February 2016.
  4. ProcessSubstitution. Greg's Wiki. 22 вересня 2016. Архів оригіналу за 11 листопада 2021. Процитовано 6 лютого 2021.