Sziasztok!
Régóta írogatok egyszerű shell scripteket bash-ban, és egy ideje elkezdtem foglalkozni a POSIX kompatibilitással (csak hobbi). Egész mostanáig alig volt problémám ezzel, a legtöbb bash dolog amivel találkoztam, könnyen elhagyható, max. kicsit többet kell gépelni, vagy nem olyan szép tőle ránézésre a program.
Most viszont olyan dologgal találkoztam, ami számomra alapvető funkció, és a POSIX-ban nincs: a pipefail kapcsoló. Nélküle egy egyszerű kis bash script is akár tízszeres méretűvé és totál átláthatatlanná válhat, ha átírom. Nagyon kényelmes és "tömör" dolog ugyanis az egy pipe-pal megoldható dolgokat egy pipe-pal megoldani :) , és aztán megnézni, volt-e hiba valahol, és külön lekezelni a dolgot. Ez pipefail nélkül így nem lehetséges.
Tapasztalt sh programozók, van erre valami egyszerű megoldás POSIX-ban?
- 2221 megtekintés
Hozzászólások
- A hozzászóláshoz be kell jelentkezni
Hát ő is pont ezt írja. (Azaz hogy eddig használta - bash alatt, de ha úgy akarja megírni a kódjait, hogy nem csak bash-ban, hanem dash/ash/ksh/stb alatt is működjön, akkor ezt kerülnie kell.)
- A hozzászóláshoz be kell jelentkezni
Tényleg, bocs.
- A hozzászóláshoz be kell jelentkezni
Sajnos egyszerű megoldás nincs. A pipefail-t még lehet kézzel emulálni, a PIPESTATUS tömbbel, de ugye POSIX shell-ben tömbök sincsenek, nemhogy PIPESTATUS :)
Alternatívák vannak.
Az egyik lehetőség, hogy a script elején létrehozol egy tmp könyvtárat a $TMPDIR alatt (vagy ha nincs beállítva, akkor a /tmp alatt, figyelve arra, hogy a script több, párhuzamosan futó példánya ne ütközzön. Továbbá telepítesz egy trap handlert, amely ezt a könyvtárat rekurzívan lepucolja. Ezután beállítod a "set -e -u -C"-t (most a -C-ben nem vagyok biztos, hogy hordozható). Végül minden pipeline-t szétbontasz önálló parancsokra, file-ból file-ba dolgozva, a temp könyvtár alatt.
Másik lehetőség, hogy a pipeline minden tagját egy shell wrapper-be forgatod, kb. így:
( cmd1 || touch hiba) | (cmd2 || touch hiba) | (cmd3 || touch hiba )
Ezt megpróbálhatod persze automatizálni elemenként valamilyen shell függvénnyel, pl.
wrapper cmd1 | wrapper cmd2 | wraper cmd3
A pipeline lefutása után megnézed, létezik-e a "hiba" file.
Nem valami szép, de az első módszer (mindent file-okban tárolni) meglepően sokat segít hibakeresésben. Persze ha nagyok a file-ok, akkor sok helyet zabálhat a /tmp alatt, meg pörgetheti a diszket is. De hát ez a hordozhatóság, annak sosincs kimagasló teljesítménye :)
- A hozzászóláshoz be kell jelentkezni
Köszi a segítséget. A fentiek alapján úgy tűnik, nem éri meg a POSIX kompatibilitással foglalkozni, hacsak nem kifejezetten követelmény.
A vicc az, hogy a POSIX kompatibilitással épp a UNIX toolbox-filozófiájának legfőbb előnyéről kellene lemondani, vagyis arról, hogy egyszerű elemi eszközöket tetszőlegesen összekötve oldjunk meg komplex problémákat.
Mindenesetre elteszem ezeket a workaround-okat, még jól jöhetnek valamikor.
- A hozzászóláshoz be kell jelentkezni