pracuję nad rurociągiem, który ma kilka punktów branżowych, które następnie merge-- one wyglądać tak:Jak mogę podzielić i ponownie połączyć STDOUT z wielu procesów?
command2
/ \
command1 command4
\ /
command3
Każde polecenie zapisuje na standardowe wyjście i wejście akceptuje pośrednictwem standardowego wejścia. STDOUT z komendy1 musi być przekazane do zarówno command2 i command3, które są uruchamiane kolejno, a ich wyjście musi być skutecznie połączone i przekazane do command4. Początkowo myślałem, że coś jak to będzie działać:
$ command1 | (command2; command3) | command4
to nie zadziała jednak, jak tylko standardowe wyjście z command2 jest przekazywana do polecenia 4, a kiedy usunąć command4 to oczywiste, że nie jest command3 przeszły odpowiedni strumień z polecenia 1 - innymi słowy, jest tak, jakby polecenie 2 wyczerpało lub pochłonęło strumień. Otrzymuję taki sam wynik z {command2; command3; } również w środku. Więc pomyślałem, że należy używać 'tee' with process substitution i próbowała to:
$ command1 | tee >(command2) | command3 | command4
Ale niespodziewanie, że nie działało - wydaje się, że wyjście komendzie command1 i wyjście command2 są rurami do command3, która powoduje błędy i tylko wyjście polecenia command3 jest podłączone do command4. I nie okaże się, że dodaje się dostaje odpowiednie wejście i wyjście do iz command2 i command3:
$ command1 | tee >(command2) >(command3) | command4
Jednak ta strumieni wyjście Command1, aby command4 jak również, co prowadzi do problemów jak command2 i command3 produkować inny specyfikacja niż command1. Rozwiązanie Mam przybył wydaje hacky, ale to działa:
$ command1 | tee >(command2) >(command3) > /dev/null | command4
To tłumi Command1 przechodzącej swoje wyjście do command4, podczas zbierania STDOUT z command2 i command3. Działa, ale czuję, że brakuje mi bardziej oczywistego rozwiązania. Czy ja jestem? Przeczytałem dziesiątki wątków i nie znalazłem rozwiązania tego problemu, który działa w moim przypadku użycia, ani nie widziałem opracowania dokładnego problemu dzielenia i ponownego łączenia strumieni (choć nie mogę być pierwszym jeden do poradzenia sobie z tym). Czy powinienem używać tylko nazwanych potoków? Próbowałem, ale miałem problemy z tym, żeby to działało, więc może to inna historia dla innego wątku. Używam bash w RHEL5.8.
Wygląda na to, że twoje pytanie ma rozwiązanie, które działa - więc czy prosisz o inne rozwiązanie? Zazwyczaj ten rodzaj podziału nie pojawia się często w skryptach powłoki, ale często występuje w specjalistycznym narzędziu, takim jak Hadoop-MapReduce - nie sądzę, że znajdziesz coś lepszego niż potok bash. – Soren
@Soren - tak, zastanawiam się, czy istnieje lepsze rozwiązanie. Nie tracę z tym snu, ponieważ moje rozwiązanie wydaje się działać, ale spodziewam się, że istnieje rozwiązanie, które nie wiąże się z przekierowywaniem stdout do/dev/null i jestem ciekawy, gdzie popełniłem błąd, ponieważ może to być pouczające dla mnie (lub innych) w miarę rozwoju. –