Załóżmy, że mam następującą potok:
a | b | c | d
Jak mogę czekać na zakończenie c
(lub b
) w sh
lub bash
? Oznacza to, że skrypt d
może się uruchomić w dowolnym momencie (i nie trzeba na niego czekać), ale c
do prawidłowego działania wymaga pełnego wyjścia .
Sprawa stosowanie jest difftool
dla git
że porównuje obrazy. Jest wywoływany git
i musi przetworzyć dane wejściowe ( a | b | c
część) i wyświetlić wyniki porównania ( d
część). Dzwoniący usunie dane wymagane dla a
i b
. Oznacza to, że przed powrotem ze skryptu proces c
(lub b
) musi zostać zakończony. Z drugiej strony nie mogę się doczekać, d
ponieważ oznacza to, że czekam na dane wejściowe użytkownika.
Wiem, że mogę zapisać wyniki c
do pliku tymczasowego lub użyć FIFO w bash
. (Nie jestem jednak pewien, czy FIFO pomoże). Czy można to osiągnąć bez tymczasowych plików sh
?
EDYTOWAĆ
Być może byłoby wystarczające, gdybym mógł w wiarygodny sposób znaleźć identyfikator procesu c
(lub b
) procesu. Wtedy cała rura mogłaby zostać uruchomiona asynchronicznie i mogłem poczekać na identyfikator procesu. Coś w stylu
wait $(a | b | { c & [print PID of c] ; } | d)
EDYCJA ^ 2
Znalazłem rozwiązanie, komentarze (lub jeszcze lepsze rozwiązania) są mile widziane.
d
rozpocząć przetwarzanie danychc
wyjściowych dopiero poc
zakończeniu? Nie chceszd
rozpoczynać przetwarzania każdej linii wyjściowej, jaka się pojawi?d
można rozpocząć, kiedy tylko chce, alec
musi się skończyć, zanim będę mógł przejść dalej.d
można zacząć, kiedy chce, na co dokładnie czekasz?d
nie używa danych wyjściowychc
, wydaje się, że nie ma sensud
wchodzić w skład potoku. Ale jeślid
korzysta z danych wejściowych, tod
po ich przeczytaniu musi działać chwilę po ich przeczytaniu, aby Twoje podejście miało jakąkolwiek różnicę.Odpowiedzi:
Powiadomienia można dokonać np. Przez sygnał do PID, który został przekazany w zmiennej środowiskowej (
kill -USR1 $EXTPID
) lub przez utworzenie pliku (touch /path/to/file
).Inny pomysł:
Wykonujesz następny proces (ten, aby móc rozpocząć, na który czekasz) z potoku:
lub
źródło
notify
może być wykonany zanim ustawię pułapkę sygnału. Jak mogę się upewnić, że nie przegapię tego sygnału?trap
zdefiniowaniu.{ c; bg; }
lub{ c; exit 0; }
nie działa.Jeśli dobrze rozumiem twoje pytanie, powinno to działać:
(sztuczka fd 3 jest spowodowana tym, że niektóre (większość) powłok przekierowuje standardowe wejście na / dev / null za pomocą
&
).źródło
W bash możesz użyć podstawienia procesu . Polecenie w procesie podstawiania działa asynchronicznie, nie jest czekane.
źródło
bash
tylko prawda, braksh
wsparcia?Oto, co znalazłem metodą prób i błędów przy pomocy informacji Hauke:
Odpowiednio:
(To ostatnie jest bardziej wyraźne, ponieważ i tak
{}
będzie działać w podpowłoce, jeśli będzie w potoku).Niektóre inne sygnały (włącznie
QUIT
,TERM
iUSR1
) działają też jednak w tym przypadku opis sygnału jest wyświetlany na terminalu.Zastanawiam się, czy taka jest pierwotna intencja
PIPE
sygnału. Zgodnie z instrukcją :Oznacza to, że kiedy sztucznie wysyłam sygnał potoku do podpowłoki, po cichu kończy się, pozostawiając końcowego konsumenta (
d
) samego.Działa to zarówno
sh
ibash
.źródło
Możesz użyć
sponge
programu z pakietu „moreutils”:a | b | c | sponge | d
gąbka będzie na końcu
c
wyjścia przed podłączeniem do niegod
. Mam nadzieję, że tego właśnie chciałeś.źródło
Możesz po prostu zrobić:
Tak więc po
d
zakończeniucat
absorbuje resztęc
mocy wyjściowej aż do jej zakończenia.Ok. Po komentarzach myślę, że odpowiedź powinna rozpocząć się bezpośrednio
d
w tle.Robić:
lub skorzystaj z rozwiązania Stephane Chazelas , jeśli występują problemy z
d
czytaniem ze standardowego wejścia .źródło
c
kończy się wcześniej niżd
, i muszę czekać do końca,c
ale nie przejmuję sięd
.c
skończy się id
nadal działa? Zabićd
?d
ma GUI i może działać, dopóki użytkownik go nie zamknie.a
,b
ic
zakończyć swoją pracę, oni blisko stdout i wyjść; i tylkod
działa. Czy chcesz wysłaćd
do tła poc
zakończeniu? Czy to to?d
powinien zostać wysłany do tła poc
zakończeniu.