фоновый процесс трубо-ввод

14

если я хочу отобразить «ааа» на экране:

(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) -> отдельного процесса все еще имеют подключенный выход, которым можно управлять, использовать, перенаправлять ..., но не вводить!

У меня вопрос: кто-то понимает, почему и как работает line (5) ???

... «<& 0» - это сокращение от «0 <& 0», почему перенаправление от 0 до 0 является решением, и что на самом деле происходит после ввода отдельного процесса. Subshell не являются проблемой, использование фигурных скобок {...} вместо (...) дает те же результаты.

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

Асаин Куйович
источник

Ответы:

12

Да, как того требует POSIX , команды, запускаемые в фоновом режиме &, перенаправляются со стандартного ввода /dev/null.

И действительно

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

это самый очевидный способ обойти это.

Пока не ясно, почему вы хотите запустить часть конвейера в фоновом режиме.

Стефан Шазелас
источник
причина была в том, чтобы получить PID одной конкретной команды внутри цепочки каналов (cmd1 | {cmd2 &; pid2 = $ !;} | cmd3 ..., поэтому / dev / null == & 0 является стандартным для процесса BG, вы также знаете, почему «0 <& 0» работает в bash ... и это безопасно?
Асаин Куйович
3
@OmerMerdan POSIX говорит, что во всех случаях явное перенаправление стандартного ввода должно переопределять это действие , которое каким-то образом противоречит тому, что было сказано выше, поэтому я считаю, что bashоно (и это звучит как разумная интерпретация) отменяет /dev/nullперенаправление. Сейчас не многие снаряды делают то же самое. Эш и ПДКШ нет.
Стефан Шазелас
Зачем 3<&-нужна эта деталь, и безопасно ли ее использовать (не закроет ли канал, пока не будет прочитан полный ввод)?
Мворисек
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
Стефан