Dobrym sposobem na sprawdzenie różnicy między nimi jest przeprowadzenie małego eksperymentu w wierszu poleceń. Pomimo wizualnego podobieństwa w użyciu <
postaci, robi ona coś zupełnie innego niż przekierowanie lub potok.
Użyjmy date
polecenia do testowania.
$ date | cat
Thu Jul 21 12:39:18 EEST 2011
Jest to bezcelowy przykład, ale pokazuje, że cat
zaakceptował wyjście date
STDIN i wypluł je z powrotem. Te same wyniki można osiągnąć przez podstawienie procesu:
$ cat <(date)
Thu Jul 21 12:40:53 EEST 2011
Jednak to, co stało się za kulisami, było inne. Zamiast otrzymać strumień STDIN, cat
faktycznie przekazano nazwę pliku, który musiał otworzyć i odczytać. Możesz zobaczyć ten krok, używając echo
zamiast cat
.
$ echo <(date)
/proc/self/fd/11
Gdy kot otrzymał nazwę pliku, odczytał dla nas zawartość pliku. Z drugiej strony echo po prostu pokazało nam nazwę pliku, który został przekazany. Ta różnica staje się bardziej oczywista, jeśli dodasz więcej podstawień:
$ cat <(date) <(date) <(date)
Thu Jul 21 12:44:45 EEST 2011
Thu Jul 21 12:44:45 EEST 2011
Thu Jul 21 12:44:45 EEST 2011
$ echo <(date) <(date) <(date)
/proc/self/fd/11 /proc/self/fd/12 /proc/self/fd/13
Możliwe jest połączenie podstawienia procesu (który generuje plik) i przekierowania wejściowego (które łączy plik ze STDIN):
$ cat < <(date)
Thu Jul 21 12:46:22 EEST 2011
Wygląda prawie tak samo, ale tym razem kotowi przekazano strumień STDIN zamiast nazwy pliku. Możesz to zobaczyć, wypróbowując to za pomocą echa:
$ echo < <(date)
<blank>
Ponieważ echo nie odczytuje STDIN i nie przekazano żadnego argumentu, nic nie otrzymujemy.
Potoki i dane wejściowe przekierowują zawartość wtykową do strumienia STDIN. Podstawianie procesów uruchamia polecenia, zapisuje ich dane wyjściowe w specjalnym pliku tymczasowym, a następnie przekazuje tę nazwę pliku zamiast polecenia. Każde używane polecenie traktuje to jako nazwę pliku. Zauważ, że utworzony plik nie jest zwykłym plikiem, ale nazwanym potokiem, który jest automatycznie usuwany, gdy nie jest już potrzebny.