Czy można przekierować wyjście polecenia na więcej niż jedno polecenie?

21

O ile mi wiadomo, mogę użyć polecenia tee, aby podzielić standardowe wyjście na ekran i dalsze pliki:

command -option1 -option2 argument | tee file1 file2 file3 

Czy można przekierować dane wyjściowe do poleceń zamiast do plików za pomocą tee, aby teoretycznie stworzyć ciąg poleceń?

Abdul Al Hazred
źródło
3
Wyjaśnij, co rozumiesz przez „sygnał wyjściowy” i opisz, co masz na myśli, tworząc „sieć poleceń”.
Janis,
w systemie Linux każde polecenie ma jedno wejście i dwa wyjścia. są oznaczone 0 (dla danych wejściowych), 1 (dla danych wyjściowych) i 2 (dla danych wyjściowych błędów). Myślałem o 1, kiedy powiedziałem „sygnał wyjściowy”, ponieważ przeczytałem, że polecenie tee dzieli tylko wyjście oznaczone jako 1. Kiedy powiedziałem „sieć poleceń”, nie byłem bardzo techniczny, nie jestem pewien, jak poprawnie zdefiniowano sieć matematyczny punkt widzenia, ale ja po prostu myślałem o drzewie poleceń typologicznie mówiąc, aby niektóre polecenia mogły być rodzicami więcej niż jednego polecenia podrzędnego.
Abdul Al Hazred
Dzięki za wyjaśnienie. Proszę nie używać słowa „sygnał”, ponieważ ma on specyficzne znaczenie w Uniksie, a termin ten był bardzo mylący w tym kontekście. Dzięki jeszcze raz.
Janis,
W wierszu polecenia wprowadź sygnał man -k, aby poznać specjalne znaczenie tej kluczowej koncepcji w systemach UNIX i Linux. zabijanie ludzi byłoby dobrą stroną na początek.
Rob
Ponadto wiele osób określa stdin stdout i stderr jako „strumienie” wejściowe lub wyjściowe. Są jak małe rzeki danych, stąd strumień. Miałeś rację, szukając słowa, aby opisać je zbiorowo, ale sygnał jest po prostu złym słowem.
Rob

Odpowiedzi:

25

Możesz użyć nazwanych potoków ( http://linux.die.net/man/1/mkfifo ) w wierszu poleceń teei mieć odczyt poleceń na nazwanych potokach.

mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2

Po commandzakończeniu teezamyka nazwane potoki, które zasygnalizują EOF (odczyt 0 bajtów) na każdym z nich, /tmp/dataNktóry normalnie zakończyłby cmdNprocesy. Prawdziwy przykład:

$ mkfifo /tmp/data0 /tmp/data1 /tmp/data2
$ wc -l < /tmp/data0 & wc -w < /tmp/data1 & wc -c < /tmp/data2 &
$ tee /tmp/data0 /tmp/data1 /tmp/data2 < /etc/passwd >/dev/null
$ 61
1974
37

Z powodu procesów w tle powłoka zwróciła monit przed wyjściem programu. Wszystkie trzy przypadki wczakończyły się normalnie.

Arcege
źródło
1
W bash możesz bezpiecznie pisać przez /tmp/data/{0,1,2}. Z drugiej strony, w bashu możesz użyć substytucji procesu i mkfifocałkowicie pominąć
Tobias Kienzler
2
Może chcesz zmienić / dev / data0 na / tmp / data0. Dziękujemy również za odpowiedź na pytanie w sposób agnostyczny. Jest to bardziej pomocne niż zakładanie, że wszyscy używają bash.
abonet
15

Jeśli dobrze rozumiem, szukasz ekwiwalentu tee file1 file2 file3, ale zamiast zapisywać te same dane w trzech plikach file1, file2i file3chcesz połączyć te same dane w trzy polecenia cmd1, cmd2i cmd3, tj.

… | ??? cmd1 cmd2 cmd3

powinno być równoważne z

… | cmd1 &
… | cmd2 &
… | cmd3 &

z wyjątkiem tego, że wykonano by to tylko raz.

Można to zrobić na dwa sposoby.

Ksh93, podstawianie procesów bash i zsh . Jest to uogólnienie potoków, które pozwala argumentowi polecenia być plikiem, który po zapisaniu przekazuje dane jako dane wejściowe do polecenia (istnieje również wariant wejściowy, który po odczytaniu uzyskuje dane wyjściowe polecenia) . To jest,

echo hello | tee >(cmd1)

drukuje hellona standardowe wyjście, a ponadto prowadzi cmd1ze hellojako wejście.

Na przykład, jeśli chcesz powielić dane wejściowe somecommandi przekazać je do obu cmd1i cmd2, możesz użyć

somecommand | tee >(cmd1) | cmd2

Jeśli twoja powłoka nie obsługuje zastępowania procesów, możesz zamiast tego użyć nazwanych potoków. Zobacz odpowiedź Arcege, aby dowiedzieć się, jak to działa. Nazwane potoki są mniej wygodne niż podstawianie procesów, ponieważ musisz je utworzyć i usunąć, a także ręcznie uruchomić i zsynchronizować procesy. Mają tę zaletę, że są w pełni przenośne, podczas gdy nie wszystkie powłoki obsługują zastępowanie procesów. Mogą być również używane w scenariuszach innych niż te, dla których proces jest zastępowany.

Pod niektórymi systemami pod maską proces zamiany używa nazwanych potoków wewnętrznie. Jednak w większości systemów korzysta z nazwanych plików reprezentujących deskryptory plików .

Gilles „SO- przestań być zły”
źródło
5
Zobacz także peeod moreutils.
Stéphane Chazelas
Zauważ, że podstawienie procesu zostało wprowadzone przez ksh88.
Stéphane Chazelas,
6

Przynajmniej w możesz pominąć mkfifoużywając substytucji procesu:

command -option1 -option2 argument | tee >(cmd1) >(cmd2) >(cmd3)

lub przyjąć przykład Arcege'a

tee >(wc -l) >(wc -w) >(wc -c) < /etc/passwd >/dev/null
Tobias Kienzler
źródło