<Попередній | зміст | Наступна>
Заміна процесу
Хоча вони виглядають схожими і можуть використовуватися для об’єднання потоків для переспрямування, існує важлива відмінність між груповими командами та підоболонками. У той час як групова команда виконує всі свої команди в поточній оболонці, підоболонка (як випливає з назви) виконує свої команди в дочірній копії поточної оболонки. Це означає, що середовище копіюється та передається новому екземпляру оболонки. Коли підоболонка виходить, копія середовища втрачається, тому будь-які зміни, внесені до середовища підоболонки (включаючи призначення змінних), також втрачаються. Тому в більшості випадків, якщо для сценарію не потрібна підоболонка, групові команди є кращими, ніж підоболонки. Групові команди працюють швидше і потребують менше пам’яті.
Ми бачили приклад проблеми середовища підоболонки в розділі 28, коли виявили, що зчитування команда в конвеєрі не працює, як ми могли б інтуїтивно очікувати. Нагадаємо, якщо ми побудуємо конвеєр так:
echo "foo" | прочитати echo $REPLY
echo "foo" | прочитати echo $REPLY
Зміст ВІДПОВІДЬ змінна завжди порожня, оскільки зчитування Команда виконується в підоболонці, а її копія ВІДПОВІДЬ знищується, коли підоболонка завершується.
Оскільки команди в конвеєрах завжди виконуються в підоболонках, будь-яка команда, яка призначає змінні, зіткнеться з цією проблемою. На щастя, оболонка забезпечує екзотичну форму розширення, що називається процес заміщення які можна використовувати для вирішення цієї проблеми.
Заміщення процесу виражається двома способами: Для процесів, які виробляють стандартний вихід:
<(список)
або для процесів, які беруть стандартний вхід:
>(список)
де список це список команд.
Щоб вирішити нашу проблему с зчитування, ми можемо застосувати заміну процесу таким чином:
read < <(echo "foo") echo $REPLY
read < <(echo "foo") echo $REPLY
Підстановка процесу дозволяє нам розглядати вихід підоболонки як звичайний файл для цілей перенаправлення. Насправді, оскільки це форма розширення, ми можемо вивчити його реальну цінність:
[me@linuxbox ~]$ echo <(echo "foo")
/dev/fd/63
[me@linuxbox ~]$ echo <(echo "foo")
/dev/fd/63
Працюючи з нудьгувати щоб переглянути результат розширення, ми бачимо, що вихід підоболочки надається файлом з іменем /dev/fd/63.
Заміщення процесу часто використовується з циклами, що містять зчитування. Ось приклад а
цикл читання, який обробляє вміст списку каталогу, створеного підоболонкою:
#! / бін / баш
# pro-sub: демонстрація заміни процесу
while read attr links власник групи розмір дата час ім'я файлу; do cat <<- EOF
Ім'я файлу: $filename Розмір: $size
Власник: $owner
Група: $group Змінено: $date $time Посилання: $links Атрибути: $attr
EOF
виконано < <(ls -l | хвіст -n +2)
#! / бін / баш
# pro-sub: демонстрація заміни процесу
while read attr links власник групи розмір дата час ім'я файлу; do cat <<- EOF
Ім'я файлу: $filename Розмір: $size
Власник: $owner
Група: $group Змінено: $date $time Посилання: $links Атрибути: $attr
EOF
виконано < <(ls -l | хвіст -n +2)
Цикл виконується зчитування для кожного рядка списку каталогу. Сам перелік створюється в останньому рядку сценарію. Цей рядок перенаправляє вихід підстановки процесу на стандартний вхід циклу. The хвіст Команда включена в конвеєр підстановки процесу, щоб видалити перший рядок списку, який не потрібен.
Після виконання скрипт видає такий результат:
[me@linuxbox ~]$ про-суб | голова -n 20
Ім'я файлу: addresses.ldif Розмір: 14540
Власник: я
Група: я
Modified: 2009-04-02 11:12
[me@linuxbox ~]$ про-суб | голова -n 20
Ім'я файлу: addresses.ldif Розмір: 14540
Власник: я
Група: я
Modified: 2009-04-02 11:12
Посилання:
1
Посилання:
Атрибути: -rw-r--r--
Ім'я файлу: bin
Розмір: 4096
Власник: я
Група: я
Modified: 2009-07-10 07:31
Посилання: 2
Атрибути: drwxr-xr-x
Ім'я файлу: bookmarks.html Розмір: 394213
Власник: я
Група: я
Атрибути: -rw-r--r--
Ім'я файлу: bin
Розмір: 4096
Власник: я
Група: я
Modified: 2009-07-10 07:31
Посилання: 2
Атрибути: drwxr-xr-x
Ім'я файлу: bookmarks.html Розмір: 394213
Власник: я
Група: я

документація