Za bash
pomocą mogę zastąpić proces i traktować dane wyjściowe procesu tak, jakby to był plik zapisany na dysku:
$ echo <(ls)
/dev/fd/63
$ ls -lAhF <(ls)
lr-x------ 1 root root 64 Sep 17 12:55 /dev/fd/63 -> pipe:[1652825]
niestety, zastępowanie procesów nie jest obsługiwane w dash
.
Jaki byłby najlepszy sposób na emulację Process Substitution
w desce rozdzielczej?
Nie chcę gdzieś zapisywać wyniku jako pliku tymczasowego ( /tmp/
), a następnie muszę go usunąć. Czy istnieje alternatywny sposób?
process-substitution
dash
Martin Vegter
źródło
źródło
bash
na swoim urządzeniu?/dev/fd
i używaniaxz -cd <file>
zamiastcat <file> | xz -d
)xz -cd "$1" | { xz -cd "$2" | { diff /dev/fd/3 /dev/fd/4; } 3<&0; } 4<&0
.Odpowiedzi:
Pytanie w aktualnym ogłoszeniu o nagrodę:
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:
(Używanie
file1.xz
zamiast"$1"
dla czytelności ixz -cd
zamiastcat ... | 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 pliku3
, 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.
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
icmd1
nacmd2 | { 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ćbędziesz potrzebować czegoś takiego
1 Więcej na ich temat można znaleźć w U&L, np. W Understanding / dev oraz jego podkatalogach i plikach .
źródło
Możesz odtworzyć to, co robi skorupa pod maską, wykonując czynności hydrauliczne ręcznie. Jeśli twój system ma wpisy, możesz użyć tasowania deskryptorów plików: możesz tłumaczyć
/dev/fd/NNN
do
Pokazałem bardziej złożony przykład ilustrujący wiele wejść i wyjść. Jeśli nie musisz czytać ze standardowego wejścia, a jedynym powodem, dla którego używasz podstawiania procesów, jest to, że polecenie wymaga jawnej nazwy pliku, możesz po prostu użyć
/dev/stdin
:Bez tego musisz użyć nazwanego potoku . Nazwany potok jest pozycją katalogu, więc musisz gdzieś utworzyć plik tymczasowy, ale ten plik to tylko nazwa, nie zawiera żadnych danych.
/dev/fd/NNN
źródło
</dev/fd/8 >/dev/fd/9
nie są równoważne z<&8 >&9
Linuksem i należy ich unikać.diff <(cat "$2" | xz -d) <(cat "$1" | xz -d)
?Myślę, że nazwane potoki są łatwiejsze do odczytania niż przekierowania, więc najprościej mówiąc:
p1
ip2
są tymczasowymi nazwanymi potokami, można je nazwać dowolnymi.Byłoby mądrzejsze tworzyć rury
/tmp
, np. W katalogu, jak pokazuje odpowiedź Gillesa , i zauważ, że nie potrzebujeszcat
tutaj, więc:(Prawdopodobnie możesz też uciec bez cudzysłowów, ponieważ
mktemp
prawdopodobnie stworzysz „ładne” nazwy plików).Rozwiązanie potoku ma zastrzeżenie, że jeśli główne polecenie (
diff
) umrze przed odczytaniem wszystkich danych wejściowych, procesy w tle mogą pozostać zawieszone.źródło
Co powiesz na:
źródło