W zsh różnica między cat <(cat) vs cat | kot vs kot = (kot)?


18

Spodziewałem się cat <(cat)i cat | catzrobię to samo: skopiuj wiersze ze standardowego wejścia na standardowe wyjście. Zrozumiałem, że oba wykonałyby a catw podpowłoce, przekierowały catstdout podpowłoki do tymczasowej nazwanej potoki, a następnie wykonały inną catw bieżącej powłoce ze stdin przekierowanym do potoku.

Zamiast tego cat <(cat)pozwala mi pisać na moim terminalu, ale żadna z linii wejściowych nie jest kopiowana i ^Dnie jest sygnalizowana EOF; cat | catdziała zgodnie z oczekiwaniami.

W kolejnym eksperymencie sprawdziłem, czy cat =(cat)ma podobne trudności cat <(cat), ale działa tak, jak się spodziewałem: wszystkie stdin do jednego ^Dsą kopiowane na stdout za jednym razem.

Czy ktoś może mi pomóc zrozumieć, co robi Zsh pod maską?

Odpowiedzi:


23
  1. a | błączy się STDOUTz ai STDINze btylko za pomocą dup/dup2. Oba polecenia są wykonywane równolegle.

  2. a =(b)zastępuje argument atymczasową nazwą pliku. bzostanie wykonany wcześniej, aponieważ plik tymczasowy musi zostać utworzony, zanim będzie można go przekazaća

  3. a <(b)zamienia argument na anazwany potok. ai bbiegną równolegle. Teraz jest to trochę skomplikowane:

    bznajduje się w tle i nie może czytać z terminala. Możesz to przetestować samodzielnie, używając narzędzia strace -p $PIDdołączania do procesu drugiego kota, aby zobaczyć proces.

    aw międzyczasie próbuje czytać z nazwanego potoku, ale nie może nic odczytać, ponieważ bnie może czytać.

    • Oznacza to, że w zasadzie masz impas, w którym próbujesz aczytać, bale bnie możesz czytać STDINi nie możesz pisaća

Więcej informacji o procesie w tle i terminalu z man bash :

Aby ułatwić implementację interfejsu użytkownika do kontroli zadań, system operacyjny utrzymuje pojęcie bieżącego identyfikatora grupy procesów terminalowych . Członkowie tej grupy procesów (procesy, których identyfikator grupy procesów jest równy bieżącemu identyfikatorowi grupy procesów końcowych) odbierają sygnały generowane z klawiatury, takie jak SIGINT . Mówi się, że procesy te są na pierwszym planie . tłoprocesy to te, których ID grupy procesów różni się od terminala; takie procesy są odporne na sygnały generowane przez klawiaturę. Tylko procesy pierwszoplanowe mogą odczytywać z lub, jeśli użytkownik określa to za pomocą stty tostop, zapisywać do terminala. Procesy w tle, które próbują odczytywać (zapisywać, gdy działa stty tostop), terminal wysyła sygnał SIGTTIN (SIGTTOU) przez sterownik terminala jądra, który, jeśli nie zostanie złapany, zawiesza proces.


Świetnie, dziękuję - to dużo wyjaśniło!
Alan O'Donnell,

1
Zauważ, że gdy nie jest interaktywny, zsh przekierowuje standardowe wejście poleceń w tle (łącznie z tymi w <(cmd)) do /dev/null, więc zachowanie jest inne ( zsh -c 'cat <(cat)'zwraca natychmiast i nic nie wypisuje).
Stéphane Chazelas
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.