Z tego wiersza poleceniafu :
$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)
Wydaje się, że jest to wiele standardowych danych wejściowych, ale --- jeśli dobrze pamiętam mój kurs Linux Porgramming --- to nie może być to. Myślałem, że z definicji standardowe wejście to jeden strumień.
Być może ma to związek ze stdin? Czy ktoś może mi to wyjaśnić; może podać linki do dokumentacji.
Bonus: Jak skrypt poradziłby sobie z tymi wieloma strumieniami? Jeśli ktoś mógłby podać przykład w języku Python lub Perl, byłoby to bardzo pomocne.
<(…)
; w procesie Zsh składnia podstawiania to=(…)
.Odpowiedzi:
To nie jest wiele standardowych danych wejściowych. Jest to bashizm, który nazwał „Process Substitution” http://tldp.org/LDP/abs/html/process-sub.html
Tworzy pseudo plik (
/dev/fd/something
) dla każdego podstawienia. To całkiem przydatne. Polecenie może być odczytywane tylko jako strumień, co oznacza, że nie może przesuwać się tam iz powrotem z fseek. Musi to odczytać jako strumień bajtów, jak potok.BONUS Odpowiedź
Nie musisz robić zbyt wiele, aby z tego korzystać. Jeśli chodzi o skrypt, otrzymuje on poprawną nazwę pliku w wierszu poleceń, którą można otworzyć () jak wszystko inne. Jak powiedzieli inni, zobaczysz
diff /dev/fd/XX /dev/fd/YY
. Jeśli wykonasz stat () na dowolnym z tych pseudoplików, zobaczysz, że jest to nazwany potok i powinieneś traktować go semantyką potoku - mianowicie bez fseek () lub ftell (). Jeśli wykonasz test stat (), aby wyraźnie sprawdzić, czy jest to plik (np.[ -f $1 ]
), To się zepsuje - w końcu jest to realizowane jako nazwany potok.źródło
<(...)
dokonuje zamiany w bash. Dane wyjściowe procesu w parens są wysyłane do dodatkowego deskryptora pliku poza normalnym 3, a zwracana jest nazwa pliku odpowiadająca temu deskryptorowi pliku. W ten sposób dane wyjściowe polecenia można traktować jako nazwę pliku, która ma zostać przekazana do innego polecenia.źródło
Dla każdego procesu jest jeden
stdin
i jeden . Zazwyczaj są one podłączone do terminala, ale można je przekierowywać osobno.stdout
W tym przykładzie
wget
zaangażowane są dwa procesy, z których każdy ma swój własnystdin
istdout
. Każdywget
proces pisze-
, co jest jegostdout
. Następniebash
podstawienie procesu<(...)
łączystdout
proces z unikalnym pseudoplikiem, z któregodiff
można odczytać. Zauważ, że dwie zamiany procesów dają dwa różne pseudopliki!diff
Widzi więc coś takiego:gdzie
stdout
owget -q -O - URL1
jest podłączony do/dev/fd/XX
, istdout
odwget -q -O - URL2
celu/dev/fd/YY
.źródło