Pytanie w aktualnym ogłoszeniu o nagrodę:
ogólny przykład jest zbyt skomplikowany. Czy ktoś może wyjaśnić, jak wdrożyć następujący przykład?diff <(cat "$2" | xz -d) <(cat "$1" | xz -d)
wydaje się, że ma tutaj odpowiedź .
Jak pokazano w odpowiedzi Gillesa , ogólną ideą jest wysyłanie danych wyjściowych poleceń „producenta” do nowych plików urządzeń 1 na różnych etapach potoku, udostępniając je poleceniom „konsumenta”, które mogą przyjmować nazwy plików jako argumenty ( zakładając, że twój system daje ci dostęp do deskryptorów plików as /dev/fd/X
).
Najprostszym sposobem na osiągnięcie tego, czego szukasz, jest prawdopodobnie:
xz -cd file1.xz | { xz -cd file2.xz | diff /dev/fd/3 -; } 3<&0
(Używanie file1.xz
zamiast "$1"
dla czytelności i xz -cd
zamiast cat ... | xz -d
ponieważ wystarczy jedno polecenie).
Wyjście pierwszego polecenia „producent” xz -cd file1.xz
jest przesyłane potokowo do polecenia złożonego ( {...}
); ale zamiast zostać natychmiast wykorzystanym jako standardowe wejście następnego polecenia, jest on kopiowany do deskryptora pliku, 3
a tym samym jest dostępny dla wszystkich elementów wewnątrz polecenia złożonego jako /dev/fd/3
. Wyjście drugiego polecenia „producent” xz -cd file2.xz
, które nie wykorzystuje ani standardowego wejścia, ani niczego z deskryptora pliku 3
, jest następnie przesyłane potokowo do polecenia „konsument” diff
, które odczytuje ze standardowego wejścia i z /dev/fd/3
.
Można dodać potoki i powielanie deskryptorów plików w celu zapewnienia plików urządzeń dla dowolnej liczby poleceń „producenta”, np.
xz -cd file1.xz | { xz -cd file2.xz | { diff /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
Chociaż może to być nieistotne w kontekście konkretnego pytania, warto zauważyć, że:
cmd1 <(cmd2) <(cmd3)
, cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
I ( cmd2 | ( cmd3 | ( cmd1 /dev/fd/3 /dev/fd/4 ) 4<&0 ) 3<&0 )
mają różne potencjalne skutki dla środowiska wykonywania początkowej.
Wbrew temu, co dzieje się cmd1 <(cmd2) <(cmd3)
, cmd3
i cmd1
na cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
nie będzie w stanie odczytać żadnych danych od użytkownika. Będzie to wymagało dalszych deskryptorów plików. Na przykład, aby dopasować
diff <(echo foo) <(read var; echo "$var")
będziesz potrzebować czegoś takiego
{ echo foo | { read var 0<&9; echo "$var" | diff /dev/fd/3 -; } 3<&0; } 9<&0
1 Więcej na ich temat można znaleźć w U&L, np. W Understanding / dev oraz jego podkatalogach i plikach .