Process substitution
Process substitution, czyli w wolnym tłumaczeniu “podstawienie procesu” to
rodzaj komunikacji międzyprocesowej, który umożliwia przekierowanie wyjścia
jednego programu na wejście innego. Odbywa się to bardzo podobnie jak utworzenie
nienazwanego potoku przy pomocy operatora pałki |
, z tą różnicą, że na wejście
jednego programu mogą zostać przekierowane wyjścia z wielu programów.
Process substitution zapisywany jest poprzez użycie operatora <()
. Technika ta
umożliwia przekazanie wyjść programów w miejsce, gdzie inny program normalnie
otrzymuje listę argumentów będących jego plikami wejściowymi. Przykładowo
poniższe wywołanie spowoduje porównanie zawartości dwóch katalogów:
$ diff <(ls dir1) <(ls dir2)
Oczywiście wywołania mogą być łączone. Poniżej nieco bezsensowny przykład otwarcia w Vimie przegrepowanej skrzynki odbiorczej:
$ vim <(grep -e "From" <(head -n100 ~/mbox))
Działa to również w drugą stronę. Jeśli możemy podać komendzie plik wyjściowy
(czyli taki, do którego będzie pisała), to przy pomocy operatora >()
możemy w
to miejsce podstawić wejście innego programu. Przykładowo, poniższe wywołanie
spowoduje utworzenie dwóch plików zawierających listy plików z rozszerzeniem jpg
i png. Samo tworzenie plików zawdzięczamy, przekierowaniu wyjścia z grepa do
pliku, natomiast oba grepy otrzymają to samo wyjście z wywołania komendy ls:
$ ls | tee >(grep png > png_files) >(grep jpg > jpg_files)
Interesującym użyciem jest możliwość przekazania standardowego wyjścia do programu, który normalnie nie jest w stanie go obsłużyć. Aby to sprezentować, ponownie posłużę się głupim przykładem. Jeśli nasz zarówno nasz terminal, jak i grep obsługują kolory, powinno to spowodować podświetlenie litery “b”:
$ echo "abc" > >(grep -e "b" <(cat))
Podstawianie procesów jest nie tylko wygodne, ale i efektywne, gdyż na dysku nie są zapisywane żadne dane tymczasowe (chociaż czas dostępu do dysku w czasach dysków SSD powoli traci na znaczeniu). Co więcej, jeśli to tylko możliwe, komendy będą wywoływane równolegle.
Przy wszystkich dobrodziejstwach zaprezentowanych technik należy jednak pamiętać
o ich ograniczeniach. Przede wszystkim z wywoływanych w ten sposób komend nie
jesteśmy w stanie pobrać kodu wyjścia, a więc nie jesteśmy w stanie w prosty
sposób dowiedzieć się o powodzeniu (lub nie) komendy. Z drugiej strony, ponieważ
shell utworzy albo plik w /proc/self/fd
, albo nazwany potok, nie można
zmienić pozycji w takim “sztucznym
pliku”, co może skutkować tym, że nie wszystkie programy będą z nim dobrze
współpracować.