process substitution in bash
Cine a avut ocazia sa se uite peste umarul meu cand lucrez minim jumatate de ora stie ca am o pasiune deosebita pentru "instalatii" de linie de comanda, construirea de one-linere cu multe pipe-uri si redirectari. Una din probleme era ca "teava" la care lucrezi pare sa fie obligatoriu liniara, dat fiind ca singura metoda aparenta de a da date dinamice unui proces e via pipe direct in stdin. Adevarat, poti sa mai pui cate un "robinet" cu tee, dar outputul esti obligat sa-l dai intr-un fisier (sa folosesc terminologie de VCS, poti face branching, dar mai complicat cu merge-urile). Asta e enervant de exemplu cand vrei sa faci diff intre outputul la doua comenzi. Cand e doar o comanda si un fisier, bagi comanda cu pipe in stdin si treci - ca argument, dar daca o vrei si pe a doua, trebuie sa faci fisiere temporare sau socketi pe care sa ai grija sa-i cureti si evident ca sa nu conflicteze cu altceva ajungi in complicatii cu mktemp etc.
NOT ANYMORE!
Multumita unui articol gasit prin agregatorul meu de rss-uri (offtopic: google reader rulez) am dat peste feature-ul bashului care se cheama "process substitution". Nu este vorba de "command substitution", cea cu backtickuri sau $() ci ceva similar, dar mult mai tare.
Pe scurt, daca in linia de comanda apare ceva gen <(comanda) , bash ruleaza "comanda" ca proces separat si creeaza un socket in /dev/fd/ pe care il trece in locul expresiei cu pricina. Exemplu : echo <(echo) . De notat ca /dev/fd/ e tratat special de bash si exploratul lui se poate dovedi nitel mai dificil. Okay, okay, recunosc ca nu stiu _exact_ ce se intampla si ca mi-e lene sa ma uit in surse. Dar efectul e deosebit. De exemplu: diff -Nu <(route -n|sort -n) <(ssh server route -n | sort -n).
De notat ca merge si invers: >(comanda) e inlocuit cu un nume e fisier in care ce scrii ajunge la stdin-ul comenzii cu pricina. In scripturi mici e cam ca un pipe scris pe dos, dar pare o metoda foarte eleganta pt. utilizarea de fifo-uri in scripturi mai mari.
Atentie e un feature relativ nou si ca atare nu e foarte portabil. In plus, inlocuirea expresiei se face de catre bash in momentul interpretarii liniei (pentru detalii referitoare la ordine, recomand cu caldura man bash), ca atare imbricarile se pot dovedi ceva mai complicate, necesita heavy quoting skills si lamurirea neclaritatilor pe care le aveam mai sus privitor la detaliile mecanismului cu /dev/fd/. Dar tot e cool
Asociatia "Mario Brothers" a Instalatorilor in Linie de Comanda va ureaza spor la infiletat!