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

Історія ред.

Процесне заміщення було доступне для вибору при компіляції в 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.