wejście potoku procesu w tle

14

jeśli chcę wyświetlić „aaa” na ekranie:

(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

wniosek z (3) i (4) -> odłączony proces nadal ma podłączone wyjście, które można kontrolować, wykorzystywać, przekierowywać ..., ale nie wprowadzać!

Moje pytanie brzmi: czy ktoś rozumie, dlaczego i jak działa linia (5) ???

... „<& 0” to skrót od „0 <& 0”, dlaczego przekierowanie 0 na 0 jest rozwiązaniem i co tak naprawdę dzieje się z wejściem odłączonego procesu. Podkładki nie stanowią problemu, używanie nawiasów klamrowych {...} zamiast (...) zapewnia takie same wyniki.

... i pytanie 2: czy istnieje lepsze rozwiązanie dla „przekazywania danych wejściowych procesowi odłączonemu” niż linia (6).

Asain Kujovic
źródło

Odpowiedzi:

12

Tak, zgodnie z wymaganiami POSIX , polecenia uruchamiane w tle z &przekierowaniem ich standardowego wejścia /dev/null.

I rzeczywiście

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

jest najbardziej oczywistym sposobem obejścia tego.

Nie jest jednak jasne, dlaczego chcesz uruchomić część rurociągu w tle.

Stéphane Chazelas
źródło
powodem było uzyskanie PID jednego konkretnego polecenia w łańcuchu rur (cmd1 | {cmd2 &; pid2 = $ !;} | cmd3 ..., więc / dev / null == & 0 jest standardem dla procesu BG, czy wiesz również dlaczego "0 <& 0" działa w bash ... i czy jest to bezpieczne?
Asain Kujovic
3
@OmerMerdan POSIX mówi: We wszystkich przypadkach wyraźne przekierowanie standardowego wejścia zastąpi tę aktywność , co jest w pewien sposób sprzeczne z tym, co zostało powiedziane powyżej, więc uważam, że bashinterpretuje to (i to brzmi jak rozsądna interpretacja) jako anulowanie /dev/nullprzekierowania. Teraz niewiele pocisków robi to samo. Ash i pdksh nie.
Stéphane Chazelas,
Dlaczego ta 3<&-część jest potrzebna i czy można z niej bezpiecznie korzystać (czy nie zamknie rury przed pełnym wejściem odczytanym)?
mvorisek
1
@Mvorisek, że fd 3 jest używany tylko tymczasowo do przywrócenia oryginalnego wejścia. Zamykamy, ponieważ cmdnie jest to potrzebne. Zamykamy go po skopiowaniu go na fd 0 ( <&3skrót od 0<&3).
Stéphane Chazelas,
1
@Mvorisek, nohupprzekierowuje również stdin do / dev / null, więc należałoby: { nohup sh -c 'cmd <&3 3<&-' & } 3<&0. Lub(trap '' HUP; cmd <&3 3<&- > nohup.out 2>&1 &) 3<&0
Stéphane Chazelas