фон трубопровідного вводу


14

якщо я хочу відобразити "aaa" на екрані:

(1)$: echo aaa | cat                 ... works OK
(2)$: echo aaa | ( cat )             ... works OK
(3)$: echo aaa | ( cat & )           ... NOT working
(4)$: ( echo aaa & ) | cat           ... works OK 
(5)$: echo aaa | ( cat <&0 & )       ... works ok in BASH (but not in SH)
(6)$: echo aaa | ( cat <&3 & ) 3<&0  ... works ok in BASH and SH

Виключення з (3) та (4) -> відокремленого процесу все ще мають підключений вихід, який можна керувати, використовувати, перенаправляти ..., але не вводити!

Моє запитання: чи хтось розуміє, чому і як працює лінія (5) ???

... "<& 0" є скороченням "0 <& 0", чому перенаправлення 0 на 0 - це рішення, а що насправді відбувається позаду при введенні окремого процесу. Абонемент не є проблемою, використовуючи дужки {...} замість (...) дають однакові результати.

... і питання2: чи є краще рішення для "надання вводу в окремий процес", ніж рядок (6).

Відповіді:


12

Так, як того вимагає POSIX , команди, запущені у фоновому режимі, &мають перенаправити стандартний вхід з /dev/null.

І справді

{ cmd <&3 3<&- & } 3<&0

це найбільш очевидний спосіб обійти це.

Не ясно, чому ви хочете запустити частину конвеєра у фоновому режимі.


Причина полягала в тому, щоб отримати PID однієї конкретної команди всередині ланцюга труб (cmd1 | {cmd2 &; pid2 = $ !;} | cmd3 ..., тому / dev / null == & 0 є стандартним для BG процесу, чи ви також знаєте, чому "0 <& 0" працює в баші ... і чи безпечно це?
Асаїн Куйович

3
@OmerMerdan POSIX каже, що у всіх випадках явне перенаправлення стандартного вводу повинно перекривати цю діяльність , яка певним чином суперечить сказаному вище, тому я вважаю, що bashце трактує (і це звучить як розумне тлумачення) як скасування /dev/nullпереадресації. Зараз не багато снарядів роблять те саме. Зола та пдкш ні.
Стефан Шазелас

Чому саме ця 3<&-частина потрібна і чи безпечно її використовувати (чи не закриє вона трубу до повного введення, якщо вона прочитана)?
mvorisek

1
@Mvorisek, що fd 3 використовується лише тимчасово для відновлення початкового stdin. Ми закриваємо його як cmdне потрібно. Ми закриваємо його після того, як ми скопіювали його на fd 0 ( <&3скорочено для 0<&3).
Стефан Шазелас

1
@Mvorisek, nohupтакож перенаправляє STDIN в / DEV / нуль, так що вам потрібно: { nohup sh -c 'cmd <&3 3<&-' & } 3<&0. Або(trap '' HUP; cmd <&3 3<&- > nohup.out 2>&1 &) 3<&0
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.