[MEGOLDVA] Linux parancs kimenetének kiiratása egy másik programban

Fórumok

Sziasztok. Olyan segítségre lenne szükségem, hogy egy használok egy minimalista filekezelőt (lf file manager), amit testre lehet szabni bash scriptekkel. Azt már megoldottam benne, hogy olyan másolási algoritmust használjak, ami kiírja, hogy %-ésoan hol tart, és progressbar-t is mutat, iilletve aszinkronként működjön. Viszont a másolás kimenetét (amit parancsorban is látni, hogy épp hol tart), azt nem tudom a státusz sorba kiíratni. A fejlesztő csinált egy példát még anno erre, csak ő az rsync -et vette alapul, és így néz ki:

cmd paste &{{
    set -- $(cat ~/.local/share/lf/files)
    mode="$1"
    shift
    case "$mode" in
        copy)
            rsync -av --ignore-existing --progress -- "$@" . |
            stdbuf -i0 -o0 -e0 tr '\r' '\n' |
            while IFS= read -r line; do
                lf -remote "send $id echo $line"
            done
            ;;
        move) mv -n -- "$@" .;;
    esac
    rm ~/.local/share/lf/files
    lf -remote "send clear"
}}

Ítt a lényeg a case-en belül a copy rész. Az rsync csinálja ugye a másolást. Ezt cserélném le az alábbi parancsra: gcp -rfp "$@" .

Viszont az stdbuf és while-done nem tlejesen tiszta. A lényegét értem, miszerint az rsync progress funkciója minden egyes file-ra külön írja ki, és ezért kell a while-done gondolom, hogy minden egyes sort ki is irasson a státusz bárra, illetőleg az stdbuf amit nem igazán értek, hogy mi, és mit csinál. Az biztos, hogy ez a kód jól működik, kiírja az lf programon belül a státuszbárra az rsync éppen aktuálisan kiírt kimenetét (ezt csinálja az lf -remote program, de ha az rsync-et lecserélem a gcp -re, akkor semmit nem jelenít meg. Azt tudni kell, hogy a gcp egy sorba írja ki a kimenetét, így gondolom a while-done-ra nem lenne szükség alapból, de valamilyen változóba bele kellene tenni a kimenetet, hogy ki tudjam iratni, mert a példában is úgy van: lf -remote "send $id echo $line" Vagyis a line változóba teszi, és azt így már ki lehet iratni az lf remote paranccsak amit a program megeszik.

Valaki esetleg jártas ebben az stdbuf parancsban, hogy a fejlesztő miért így oldotta meg?

 

MEGOLDÁS: egy másik másolásra használt program lett az alapjahttps://github.com/jarun/advcpmv

 

cmd paste &{{
    set -- $(cat ~/.local/share/lf/files)
    mode="$1"
    shift
    case "$mode" in
        copy)
            advcp -ag "$@" . | grep -Po --line-buffered "(?<=^\033\[K).+%$" | sed -nu 'p;n' |
            stdbuf -i0 -o0 -e0 tr '\r' '\n' |
            while IFS= read -r line; do
                lf -remote "send $id echo '$line'"
            done
            ;;
        move)
            if [ $size -gt 5 ]; then 
                advmv -fg "$@" . | grep -Po --line-buffered "(?<=^\033\[K).+%$" | sed -nu 'p;n' |
                while IFS= read -r line; do
                    lf -remote "send $id echo '$line'"
                done
            fi
            ;;
    esac
        rm ~/.local/share/lf/files
        lf -remote "send clear"
}}

Hozzászólások

Ha nem konzolra megy az alkalmazás kimenete, hanem másik alkalmazásba, akkor alapértelmezetten az stdlib output bufferingen (pl. 1 kB) fog csinálni, csökkentve ezzel a write() rendszerhívást.
De ezt tudod szabályozni programon belül is vagy például az stdbuf paranccsal:
   - legyen out puffer
   - legyen sorpuffer, de sorvégre írja ki
   - ne legyen semmi puffer, ha megy akár egy karakter is, abból legyen rendszerhívás

Bővebben: man stdbuf

/usr/bin/gcp:42: DeprecationWarning: Importing dbus.glib to use the GLib main loop with dbus-python is deprecated.

nagyszerű tool (gcp 0.2.0-1), egy nagyszerű disztribúcióban (Ubuntu 20.04.5 LTS)...

Első sora a gcp-nek (Ubuntu 22.10):

#! /usr/bin/python3

$ gcp -R /tmp/teszt /tmp/teszt-tmp
Copying 2.52 GiB ....

Nincs hiba. Lehet, hogy nálad még valami kivezetés alatt álló Python2 verzió van?
Netán nincs dbus, amely nélkül az ifjaknak ugyanúgy nincs élet, mint Amazon nélkül a lakás kapucsengőjével.

Teljesen friss Ubuntu 20.04.5 LTS-en volt egy apt install gcp, utána megpróbáltam elindítani, és ezt dobta. Python-ból egyébként a 3.8.10 van fent.  Mivel nekem tökéletes a sima cp/mv is, vagy épp rsync avagy a find ... | cpio -pdmv ... arra, hogy fájlokat pakolásszak ide-oda, nem foglalkoztam tovább vele. Egyébként azt akartam megnézni, hogy ez a csoda hogyan kezeli a kimenetét, mit kéne a fenti scripten mókolni, hogy működjön.
 

Mondanám, hogy ez az Ubuntu hibája, de nem az. Ez a gcp egy elég Python-gányolásnak tűnik, nekem Arch-on feltelepíteni se lehetett, elszállt valami Glib függőségi hibával, amit nem is lehetett megoldani. Az lf már egy normálisabb cucc, de azt pont nem használtam még, úgyhogy nem tudom, hogy a status bar-ba hogyan várja az infókat, meg milyen karakterekre, sortörésre, stb. érzékeny, így ebben nem tudok segíteni a témaindítónak.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Pedig Ubuntu hiba. Debian bugtrackerbe anno le lett jelentve. Amúgy a gcp-ből a legújabb verzió-ban módosította ezt, hogy ne jelezzen hibát, csak az Ubuntu 20.04 alól nem érhető el a saját repojában, de amúgy feltehető a legfrisebb.Amúgy meg Debian alatt simán felmegy, semmire nem panaszkodik, csak rendben működik, mint ahogy Ubuntu 21-estől kezdve is ha a saját caomagtárolóját nézzük.

Nézd, én nem akarok vitatkozni, meg a gcp-t ekézni, de beláthatod, hogy Archon hibás, Ubuntun problémás, akkor ezeknek az összes származékán is problémás. Jó, Debian alatt most nem, de ott is bugtrackerbe kellett jelentgetni, mire ment. Nekem ez a gcp fejleszői balfékségnek tűnik, mert nem az van, hogy ő a helikopter, az összes disztró szinte meg hülye.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Rosszul fogalmazol. Nem Ubuntun hibás, hanem csak Ubuntu 20-ason. 21-esen, 22-esen semmi gond nincsen. A 20-as meg régi verziót használ, Debianon is tökéletes, ennyi. Arch-ot meg hagyjuk. Mert az elmúlt években amennyit elb-xnak ott bármilyen csomaggal, az inkább már felháborító. Arról nem beszélve, hogy a hivatalos Arch repoban nincsen a gcp, csak az AUR-ban, ergo ha azt nem csinálja meg az illető rendesen, akkor nem is fog működni. Márpedig egy 2021-es cikk szerint mindjárt két csomagot kell feltenni az AUR-ból, hogy működjön, úgyhogy maradjunk annyiban, hogy Arch esetén egyáltalán nem meglepő, hogy nem működik, mert hivatalos útja nincsen.

Lehet, viszont ez a 0.2-es verzió sokkal többet tud, mint az eddig általam kipróbált cp variációk (a gyáriról nem is beszélve). Egyik legjobb funkciója az elemenkénti loggolás 3 féle állapottal, és gyönyörűen működik. Amúgy meg az, hogy Arch linuxon nem működik, pedig ki van rakva az AUR tárolóba, az nem a fejlesztő hibája (amúgy az AUR tároló tele van alpha állapotnak se megfelelő szoftverekkel...). Mint ahogy szerintem az sem, hogy az Ubuntu hivatalos tárolójába egy olyan verziót raktak bele, amihez eggyel frissebb dependencies kell, és nem frissítették fel az új verzióval. Mint ahogy arról sem tehet a fejlesztő, hogy xarik az Ubuntu arra, hogy frissítse, hanem inkább az újabb 21-es, 22-es verzióra terel.

Amúgy meg nem a verziószám határozza meg egy program milyenségét, mert az csak egy szám. Lehet tökéletesen működő program 0.1-es verziónál is, a fejelsztő határozza meg úgyis, míg lehet egy program 11-es verziónál, mégis egy hulladék. Ugye kedved Windows 11? :D Igen tudom, nem az a hivatalos verziószám...

Ez egy gánykupac, amit egy pájtonhuszár összelapátolt, a Buguntu-s csomagnak maximum tákolója van, nem karbantartója, estébé. Hogy a "karbantartó" meg a script elkövetője miért nem beszél egymással, az jó kérdés - az biztos, hogy egy LTS kiadásban egy ilyen prebéta cuccnak semmi keresnivalója nincs. Ha az adott LTS verzióban elérhető default python verzió nem jó neki, akkor vagy a "fejlesztője", vagy a csomag karbantartója szedje rendbe/írja át, hogy működjön - vagy hajítsák ki a repóból.

Egyébként meg akinek színes-szagos-bitkolbászos másolgatás kell, az írja meg magának - a cp parancs köszöni szépen, jól elvan, jól működik immáron 50+ éve...

Annyira prebéta szerinted, hogy Debian stable alatt tökéletesen működik, mert ott foglakoztak azzal, hogy a csomag verziószáma megfelelő legyen a linux alatt levő többi csomaggal. Attól, hogy az Ubuntu 20-as esetében esetében f-aszul csinálják (csak az Ubuntu 21 és 22-nél figyeltek erre), az továbbra sem a fejlesztő műve. A cp parancs meg pont olyan, mint 50 éve. Gyakorlatilag önmagában alkalmatlan normális műveletre. Terminálban el lehet vele bohóckodni, de ha valaki továbblép annál, akkor egy foskupac, amit ideje lenne már leváltani. Nem véletlen, hogy a komolyabb rendszermérnökök sem használják már. Sima másolásra és mozgatásra is inkább rsync-el szórakoznak, mert legalább van visszajelzés, kvóta, sávszélesség megadása stb. És ahogy nézem én is visszatérek az rsync-re, mert vele könnyen megoldható volt async működésben is a kiirartása.

A cp _neked_ alkalmatlan _szerinted_ normális műveletre. Nekem ha arra volna szükségem, hogy n darab fájlt egyedileg másoljak, _és_figyelemmel kísérhessem, hogy hol tart a másolás, akkor egy ciklus meg mondjuk egy dd háttérbe pakolva lenne az első ötletem, de lehet, hogy az rsync-et venném elő - igaz, még nem volt ilyesmire szükségem - nagyjából 30 éve...

Ezt még mindig fejlesztői hibának tartom, hogy olyan függőségei vannak a cuccnak, amit a legtöbb disztrón nem lehet kielégíteni. Maradjunk abban, hogy tényleg Pyhton-huszárságnak tűnik, pedig kár érte, mert nekem is nagyon kéne egy ilyesmi megoldás, ami normálisan mutatja, hogy hol tart a folyamat, mennyivel másol, stb..

Abban egyetértek veled, hogy a cp-t jó lenne felturbózni ma már. Annyi mostani fejlesztő ír át rustosra régi unixos toolokat, bővített funkcionalitással, hogy Dunát lehet vele rekeszteni, de a cp-t elhanyagolják ilyen szempontból, pedig arra nagyon ráférne egy modern újragondolás. Régen még elment a cp egyszerűsége, mert a minimalizmus volt a cél, hogy a PDP11-en is elmenjen pár KB RAM-mal, de a mai hardvereken meg memóriaméretnél ennyire nem kéne spórolni a funkciókkal. Ezen az értem, hogy nem kell belőle GUI-s, meg JS-es bloatot csinálni, de mondjuk írnak egy normális CLI toolt belőle, ami a mostani cp-nek teszem azt háromszorosa, még mindig 350 KB körül lenne, de modern követelményeknek megfelelően is használható. Úgy, ahogy pl. az ls funkcionalitását felturbózták az exa-val, vagy a cat-ot újragondolták bat-ként.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Lásd Ubuntu verziószámozása. Kiadási dátum (éé.hh) + bugfix  :)

A semver-t köszi. Eszerint megy a Rust crate számozása. Következmény: ahol kezdettől fogva kompatibilis visszafelé, ott 0.x.y verziószáma van a frankó rekesznek.
Például: https://crates.io/crates/num-bigint (0.4.3)
4. eredetivel felülről kompatibilis kiadás és azon belül 3. javítás.

Csak akkor lesz 1.x.y majd 2.x.y ága, ha visszafelé inkompatibilitást okozó átdolgozást kapna. Ha kompatibilis az eredetivel, akkor nem léptetik a felső számjegyet 1.0.0-ra. Így sok csomag akár 0.43.0 vagy magasabb minor számmal elvan. Persze akadnak itt is "számverseny-lovagok", akiknél a legfelső számjegy már 20 felett van, rohan a legfelső számjeggyel előre. Semver elvét követő magas minorszámú példaként a bindgen, ahol a minor számot léptetik. A bindgen-t a Linux 6.1 kernel fordítása során is használják.

/tmp-be kiírod file-ba, aztán inotify-jal eseményvezérelten kiíratod a file-odat. RAM-ba megy, tehát nem lesz szörnyen lassú. Egyébként is RAM-ba menne a disk cache miatt, de a /tmp manapság tmpfs, ami RAM, esetleg swap.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE