Shell szkript gyorsítása

A lemonbar nevű panelt használom Linuxon. Ez egy egyszerű alkalmazás, amibe be kell pipe-olni \n karakterrel lezárva, amit kiírjon, és azt kiteszi az X root képernyő tetejére egy sávba. Így írtam egy shell szkriptet, ami 0,5 másodpercenként kiírja az adatokat, ami a nyitva maradt pipe-on eléri a lemonbart. Ezzel nincs is baj, világos a működése, de egyes kiírt dolgok változhatnak idő előtt, mielőtt a szkript magától frissítené/lekérdezné őket, újra kiírná az adatokat. Ezt úgy oldom meg, hogy a "sleep 0.5" folyamatot pkill-lel kilövöm a kiírt adatok változását okozó esemény után, ami egy külön szkriptben történik (sxhkdrc). Ez alapvetően így működik is, de a panel még mindig kicsit lassan frissül, jó pár ms-os késéssel változik rajta az információ, közel fél másodperc.

Ami a kérdés lenne: ezt más lemonbar felhasználók úgy oldják meg, hogy a szkriptjük a kiírandó adatokat (hangerő, idő, stb.) egy előre, név szerint, az mkfifo paranccsal a /tmp/-be bizonyos létrehozott pipe-ba irányítják, és a lemonbar-nak csak egy a pipe-ot fprint-elik bele újabb pipe-on át:

#!/bin/sh

# bla-bla, nem érdekes részek

fifo="/tmp/panel_fifo"
mkfifo "$fifo"

# bla-bla-bla, újabb kódrészek, majd a fő while do loop végén ez jön
printf "%s\n" < "$fifo" | lemonbar

Ez mitől lenne gyorsabb, mint az én megoldásom? Csak simán pipe-olok bele a lemonbarba:
while-do-echo-szkriptem | lemonbar -kapcsolók &

Elvileg ez a hagyományos pipe-olás is a memóriában létrejött csatornába íródik, így nem értem, hogy az én megoldásomtól miben lenne jobb ez a /tmp/-be fifózás. El tudná magyarázni nekem valaki, mielőtt több órát vergődök egy újabb scriptes konfiggal? Még nem próbáltam ki, de mindenütt azt írják a neten, hogy ez a fifós megoldás gyorsabb. Először arra gondoltam, hogy a megoldásom valahol máshol selejtes, de nem, mert tényleg frissül a panel, kilövi idő előtt a szkript várakozási sleep folyamatát (ezt teszteltem), és mégis kicsit lassú. Próbáltam úgy is, hogy közvetlenül az adatváltoztató esemény előtt és után is kilövöm a sleep-es folyamatot, biztos, ami biztos, de az se gyorsít a panelfrissítésen. Gyakrabban nem akarom frissíteni fél másodpercnél az infókat, mert akkor az már túl nagy prociterhelés egy egyszerű panelért.

Hozzászólások

Például mert nem indít mindig újabb processzt?

Gábriel Ákos

Hozzál nekem a boltból egy lekváros buktát! Öööö.... :-D

Ha nem csukod be a szádat, akkor éhen maradsz!

Itt is ez a helyzet. Ha a fifo másik oldalán kukkoló ellenséggel nem beszélted meg, hogy az ööö... nálad a parancs vége, akkor még várakozni fog, hátha mondasz valamit.

A printf kezdetű sor kiolvassa a $fifo-ból az üzenet(ek)et, majd becsukja a száját, azaz küld egy EOF-ot a végén.

A programod egy fifo-n keresztül (a | is egy fifo, csak nincs neve) üzenget, de soha nem küldi az EOF-ot. Így aztán a lemonbar gondolkodok, gondolkodik és közben vár. Egy idő után rájön, hogy ez a hülye csak nem csukta be a száját és végrehajtja az olvasott utasításokat. ;)

Nem az a lényeg, hogy a parancsokat fifo-ban, fájlban vagy zacskóban gyűjtöd, hanem átadáskor jelezni kell a végét!

Ok, kösz szépen, erre voltam kíváncsi, mert nem ismerem a fifo-k és a shell lelki világát ennyire mélyen. Elvileg a lemonbar nem az EOF-ot nézi, hanem a \n karaktert (amit elküldök, nem kifejezetten \n segítésével, hanem az echo parancs küldi default), de könnyen meglehet, hogy az EOF is segíthet rajta sebességügyileg, így mindenképp kipróbálom ezt a printf < $fifo megoldást, ha tényleg gyorsít.

The world runs on Excel spreadsheets. (Dylan Beattie)

Megnéztem a lemonbar forrását - bocsánat, tévedtem.

A fifo-val működő megoldásnak teljesen más oka van.  A fifo ebben az esetben csak egy buffer, amibe aszinkron lehet írogatni a parancsokat, majd egyszerre bezuttyantani őket a lemonbar felé.

{
...
echo parancs1 >fifo &
...
echo parancs2 >fifo &
...
cat fifo
} | lemonbar

A printf "%s\n" < fifo extra \n karaktert ír a parancsok után. Itt jobb a cat vagy a printf "%s".

Mégegyszer végigolvastam a kérdést. Talán egy kicsit túlbonyolítod a dolgot. A sleep nem alkalmas pontos időzítésre, nem így kellene megoldani, meg még lőni is rá. ;)

Inkább eseményvezéreltté kellene alakítani a programodat. A sleep lejárta is egy esemény, meg a hirtelen tennivaló is esemény - mindegyik írhat azonnal, ha kell.

Rendben, kösz a helyesbítést. Még nem volt időm tesztelni, de megejtem. A lényeg, hogy javíthat a panelfrissítési időn. A \n elvileg kell a lemonbarnak, mert onnan tudja, hogy megvan minden adat a panelre, de lehet megfelel neki az EOF is, a kódját nem tanulmányoztam alaposan. Az a baj, hogy a dokumentációja nem a legjobb ennek a programnak, kitér ugyan a konfigolására, de nem tér ki a frissítésre, meg mélyebben a működési elvre.

The world runs on Excel spreadsheets. (Dylan Beattie)

Most volt időm hétvégén kipróbálni. Igaza van, ez a fifo-zás csak arra jó, hogy aszinkron lehessen frissíteni az egyes elemeket a baron. A frissítési problémát épp úgy nem oldja meg, mert ez is sleepeket használ. Egyelőre az eseményfigyelést nem próbáltam ki, ott lesz a megoldás kulcsa.

The world runs on Excel spreadsheets. (Dylan Beattie)

A dzen2 is hasonló elven működik, én azt használom (még nem volt érkezésem lemonbar-ra átírni).

Hasonló problémába én is belefutottam (tehát megtörtént valami változás és az késve íródik ki). Én azt csinálom, hogy a szkriptek, amik a változásokat figyelik, egy jelet küldenek, hogy változott, és csak akkor generálok új sort (ami a régit felülírja). Azaz ha van lehetőséged, akkor keress egy olyan hangerő-kezelőt, ami lefuttat egy parancsot, ha változott a hangerő. Vagy ha tuti biztos vagy benne, hogy csak hotkey segítségével (pl. xbindkeys) változtatsz hangerőt, akkor legyen ebben is egy jel küldve a lemonbar felé - ezáltal nem kell x másodpercenként ellenőrizgetni feleslegesen.

Másik lehetőség: pl. conky-val generálod a lemonbar-nak az inputot.

Ehhez tudnál valami konkrétabban tanácsolni? Hogyan paraméterezzem a trap parancsot, ha azt akarom, hogy pl. a SIGUSR1 szignálra indítsa újra az adott scriptet, vagy akár csak egy al-shellben futó függvényt?

Gyanítom, hogy az általam már linkelt netes szkript is valami ilyesmit csinál ebben a sorban, de nem pontosan értem a parancs részleteit:
trap 'trap - TERM; kill 0' INT TERM QUIT EXIT

Annyival tisztában vagyok, hogy a trap parancs után az első paraméter elvileg egy parancs (amit végre kell hajtani), a második paraméter a szignál, amire a parancs triggerelődik. De még nem vitézkedtem ezzel soha, így az apró trükkjeit nem ismerem. Talán csak egy régi szkriptemhez kukáztam össze ilyet a netről, amiben csak annyi kellett, hogy maga a szkript ne reagáljon a SIGKILL és SIGTERM szignálokra.

The world runs on Excel spreadsheets. (Dylan Beattie)

Ennek utána kellett néznem, mert ilyet csak C-ben írtam.

Ajánlom ezt és ezt. (végigolvasni!)

#!/bin/bash

do_nothing()
{
    :
}

trap do_nothing SIGUSR1


echo "Sleeping.  Pid=$$"

while :
do
    sleep 10 &
    SLEEP_PID=$!
    wait $SLEEP_PID
    if kill $SLEEP_PID >/dev/null 2>&1
    then
        echo "Caught SIGUSR1"
    else
        echo "Sleep over"
    fi
done

Ez a programod modellje - lehet tolni tovább a lemonbar felé.

A program 30 másodpercenkén tesz egy kört és kiírja a "Sleep over" üzenetet. Ez a periodikus tevékenység helye.

Ha küldesz egy SUGUSR1-et, akkor megszakad a wait - a biztonság kedvéért kilövi a sleep-et - és a "Caught SIGUSR1" üzenetet írja ki. Ez a külső esemény hatására végzendő tevékenység helye - vagy a do_nothing.

A futás (a promptot kitöröltem, a > a kézzel kiadott paracsot jelenti):

>p &
[1] 1708
Sleeping.  Pid=1708
Sleep over
>kill -USR1 1708
Caught SIGUSR1
Sleep over
>kill -USR1 1708
Caught SIGUSR1
>kill -USR1 1708
Caught SIGUSR1
>fg
Sleep over
./p
>^C

Kösz szépen, ki fogom próbálni, mert a saját megoldásom nem működik. Elkapja a scriptem az SIGUSR1 szignált (nem muszáj ennek lennie, tőleg lehet USR2, vagy akármilyen más értelmes szignál is), de leáll rá. Gondolom azért, mert a fő loopon kívül vizsgálom, és emiatt megszakítja a fő loopból, nem lépve bele vissza. A te megoldásod a fő loopban vizsgálja, így tényleg megoldás lehet.

Közben rájöttem, hogy a linkelt szkriptben mi az a furcsa trap - sor. Lényegében az azt csinálja, hogy ha kívülről kilövik a lemonbaros szkriptet, akkor az által hívott, subshellekben futó loopok is bezáródnak vele együtt, egyébként azon nyitva maradnának, teleszemetelve a memóriát.

The world runs on Excel spreadsheets. (Dylan Beattie)

A trap - SIGNAL törli a korábban SIGNAL-hoz rendelt handlert. (Subshellek meg loopok! :( Inkább át kellene gondolni mit csináljon a program, mintsem a "majd alkalmazok egy olyan parancsot, amiről azt sem tudom mire való".)

Az "én megoldásom" a programod modellje - signal handlerrel kiegészítve. A teszt futtatásban (ami background) a kézzel kiadott kill a "külső esemény". Erre való pl. a /tmp/pidfile (amibe beleírod a szkriptből a $$ értékét), hogy a "külső ellenség"  tudja hova lőjön.

És erre való a bash emulált EXIT signal: trap "rm -f /tmp/pidfile" EXIT

Végigolvastam a két linket, és az elsőn azt írják, amit már sejtettem. A USR1 szignálra beindul a handler shell függvény, amit megadtam neki, de cserébe abbahagyja a szkriptem fő loopját, és abba nem tér vissza. Ezt ki lehetne úgy védeni, hogy a handlernek megadott egy újabb függvényt, ami az eredetileg kívánt függvényt hívja és a loopot is újraindítja.

Amit még nem értek: a példádban a sleep-nek a USR1 szignálra való kilövése mitől jobb vagy gyorsabb, mintha magát a sleep folyamatát lőném ki kívülről, szignálozás nélkül?

The world runs on Excel spreadsheets. (Dylan Beattie)

Próbáld meg a link helyett a fenti programot futtatni. ;)

Ott van alul a futás eredménye is. Hol lép ki???

A probléma a "sleep folyamatát lőném ki kívülről" dologban van. Vajon hány szkriptet szertnél írni, amikor egyet sem látsz át?

abbahagyja a szkriptem fő loopját

Ott van, amit írtam, az potosan a szkriptednek a modellje. A signal handler nem hagyat abba semmit, csak az éppen hosszabb ideig futó parancsot. Esetünkben sajnos a sleep nem ilyen, ezért kell a sleeep 30 & ; wait kombó. Tehát a wait kilép, lefut a handler, majd a wait utáni soron folytatódik.

Az első program működése: 10 másodpercenként frissít, de ha külső esemény jön, akkor azonnal frissít és újrakezdi a 10 másodperces kört.

Itt egy másik változat, ami: 10 másodpercenként frissít. Ha külső esemény érkezik, akkor beiktat egy extra frissítést, de nem lő ki semmit.

#!/bin/bash

do_nothing()
{
        echo "Caught SIGUSR1"
}

trap do_nothing SIGUSR1


echo "Sleeping.  Pid=$$"

while :
do
    sleep 10 &
    SLEEP_PID=$!
    while ps -C -p  $SLEEP_PID >/dev/null 2>&1
    do
        wait $SLEEP_PID
    done
    echo "Sleep over"
done

A futás:

>p1 &
[1] 452
Sleeping.  Pid=452
Sleep over
Sleep over
>kill -SIGUSR1 452
Caught SIGUSR1
>kill -SIGUSR1 452
Caught SIGUSR1
Sleep over
>kill -SIGUSR1 452
Caught SIGUSR1
Sleep over
fg
p1
^C
>

Szerinted ez hol lép ki? (A végén a ^C hatására.)

Igazad van, ez lefuttatva tényleg működik, csak azt nem értem, hogy mi hajtsa ki belőle a zoxigént. Vagyis, hogy pl. wait nélkül, az előtérben futó sleep-pel ez miért nem működik, miért lenne a sleep ilyen szempontból speciális Azt még értem, hogy a wait azért kell, mert a sleepet a háttérben futtatod, de te azt nem érted, amit én nem értek, hogy minek kell a háttérben futtatni. Most lehet én vagyok gyp-s, de magas ez nekem.

The world runs on Excel spreadsheets. (Dylan Beattie)

Futtassuk a p1 programot, majd egy ps!

>p1 &
...
>ps
  PID TTY          TIME CMD
 7940 pts/5    00:00:00 sleep
 9556 pts/5    00:00:00 bash
20665 pts/5    00:00:00 p1
29866 pts/5    00:00:00 ps

A kill -SIGUSR1 9556 esetében a PID stabil, míg a sleep (/bin/sleep - external parancs) PID minden loopban más lesz.

Ezen kívül a p1-ben (PID=20665) van SIGNAL handler, de a sleep-ben nincs signal handler. A wait pedig (bash) internal  parancs, így a bash meglövésével kilép és a handler végrehajtása után folytatja a script következő soránál.

Tehát ebben az esetben implementációfüggő, mert nincs sleep internal parancs.

A C/multithread környezetben nincs ilyen probléma, mert csak egy program space van, tehát

sleep() causes the calling thread to sleep either until the
       number of real-time seconds specified in seconds have elapsed or
       until a signal arrives which is not ignored.

Higgyél nekem, már 30 éve csinálom! ;) (A Die Hard mintájára.:))

Bár a tudásomat inkább az AIX dokumentációból szereztem - az hatékonyabb, mint a fórum. ;)

Az ablakkezelő segítségével. A herbstluftwm-nek van egy kliensprogramja is, aminek van idle opciója, ami annyit csinál, hogy várakozik, amíg esemény nem jön. Eseményt saját kezűleg is kiválthatsz (emit_hook). Miután kapom az eseményt, a megfelelő infót frissítem, a többit pedig az eltárolt változókból előszedem, és kap a bar egy új sort.

Azért az ablakkezelőt használom erre, mert különböző ablakkezelős eseményeket is le lehet így "hallgatni", és reagálni rá (pl. a conky észrevehetően később frissült, mikor pl. munkaasztalt váltottam) - és minek legyen kettő eseményvezérlés, ha egy is lehet.

Szerk.: lényegében a szkript (leegyszerűsítve):

handle_event() {
  event=$1
  shift
  case ${event} in
    date)
      ;;
    task)
      update_tasks $*
      ;;
    tag_changed)
      update_tag $*
      ;;
    focus_changed)
      update_focus $*
      update_frame
      ;;
    rss)
      update_rss $*
      ;;
    rule)
      update_frame
      ;;
    window_title_changed)
      update_focus $*
      ;;
    chord_enter)
      _INCHORD="x"
      ;;
    chord_leave)
      _INCHORD=""
      ;;
  esac
  msg_all
}

herbstclient --idle | while read line; do
  handle_event ${line}
done | dzen2 -x ${_DZEN_X0} -y ${_DZEN_Y0} \
  -w ${_DZEN_WIDTH} -h ${_DZEN_HEIGHT} \
  -fn "terminus:size=8" -e 'button2=;' -ta l

Kösz a válaszokat. Egyelőre a signal küldést fogom kipróbálni trap-pel, ha az nem jön be, akkor ezt a /tmp/-be fifózást, és a fifo-buffert figyelem, hogy változott-e, ez akár az entr nevű toollal is figyelhető. Ha az sem, akkor megpróbálom ezt a herbstluftwm-es megoldást, bár ettől azért ódzkodok, mert WM-független megoldást keresek.

Lassan ott vagyok már, hogy kezd belőle elegem lenni egyébként, és visszacsábulok polybar-ra, ami ezeket a low level kérdéseket kulturáltan megoldja, és nem a usernek kell vele vergődni. Más részről viszont a polybart kicsit blaotnak tartom, messze nem használnám ki a tudását (ugyanez a bajom a Conky-val is), erre a lemonbar-ra pont azért álltam át, mert minimalistább, és nekem elég is lenne, ha ez a frissítési mizéria nem lenne vele. Nekem a dwm beépített bar-ja is elég volt, szóval azért erőltetem a lemonbart.

The world runs on Excel spreadsheets. (Dylan Beattie)

megpróbálom ezt a herbstluftwm-es megoldást, bár ettől azért ódzkodok

A herbstclient --idle részt helyettesítheted bármivel, akár pl. egy FIFO-ból való olvasással is. Ekkor nyilván a FIFO-ba fog menni az  "esemény" is. És ezzel kész a WM-független megoldás :)

Most már kezdem érteni. Nem kell nekem semmilyen herbstlicent. A while read line < $fifo elég nekem, a read parancs ilyenkor szépen kulturáltan, prociterhelés nélkül vár, amíg nem lesz a fifo-ban új adat.

Sőt, már azt is gyanítom, hogy nekem miért frissült lassan a lemonbar (procipörgetési problémán kívül is): mert az egyes kiírt infókat lekérdező parancsok az én szkriptemben sorban futottak le, négy modul a fő loopon belül: echo "$(modul1_fuggveny) ($modul2_fuggveny) ($modul3_fuggveny) ($modul4_fuggveny)". Ebben a felállásban a parancsok egymás befejezésére várnak, a soron következő parancs addig nem fut le, míg az előző be nem fejeződött, ez volt az oka a lassúságnak, ennyi parancsnál már összehalmozódtak annyira a varákozási idők, hogy késleltetésként jelentkezett. Az általam linkelt cikkben lévő, fifo-ba írogató, háttérben asszinkron frissítő modulok ezt is megoldják.

The world runs on Excel spreadsheets. (Dylan Beattie)

Közben annyival is előrejutottam, hogy a szkriptemben nem kell egy csomó modulnál sleep-eznem, sem figyelnem, hogy változott-e. Kiderült, hogy az xtitle alkalmazásnak van például -s kapcsolóra egy snoop módja, ami prociterhelés nélkül kiírja újra a fókuszban lévő ablak nevét, ha az megváltozott. Ugyanígy a bspwm-ben lévő bspc subscribe parancs is folyamatosan tudja figyelni az aktív munkaasztalt, ha megváltozott, akkor új sorba írja kimenetnek. Az időt 1 másodpercenként frissítem (bár lehet elég lenne a 60 sec is, és jobb lenne csak a percre pontosan írni), ez sem akkora terhelés.

Egyedül az van, amit írsz, hogy a hangerőt kéne kulturáltan, prociterhelés nélkül, sleep utáni felesleges újralekérdezés nélkül figyelni. Erre nem találok megoldást, pedig kell, hogy létezzen.

The world runs on Excel spreadsheets. (Dylan Beattie)

hangerőt

Két lehetőséget látok: ha biztosan tudod, hogy csak hotkey segítségével változtatod a hangerőt, akkor arra nem csak a hangerő változást rákötni, hanem az "esemény küldését" is. Másrészt meg kell nézni, hogy milyen hangrendszered van (gondolom, pulse, de azt se tudom, milyen linuxot használsz), és ott szétnézni, van-e esetleg ilyesmi parancs, amiket most írtál (pl. xtitle esetén a -s illetve bspwm-ben a subscribe).

Közben megvan a hangerő is:
pactl subscribe | grep sink > $fifo_nev

Így az órán kívül semmit nem kell már sleep-pel frissítenem, mindennek a változását tudom detektálni, CPU pörgetése nélkül a fifo-ból, ilyen subscribe-os és snoop-os megoldásokkal.

The world runs on Excel spreadsheets. (Dylan Beattie)

Azt inkább nem, az nagyon bonyolult. Maradok az egyszerű megoldásnál:
while true; do date "+formatumfelsorolas"; sleep 1_vagy_60; done > $fifo_nev &

Egyelőre eddig beválik, ezekkel a snoopingolós újításokkal és a fifo-ba asszinkron írogatós, majd while read line; do ...; done segítségével feldolgozós megoldás segített a problémán. A prociterhelés 0-ra ugrott vissza, és minden eseményre azonnal, villám módon reagál és frissül a panel. Nem kell hozzá sleep, nem kell hozzá -USR1 szignálfigyelés.

A hangerőfigyelés nem tökéletes. A pactl subscribe | grep sink parancs két soronként írogat a fifo-ba (a pactl a bal és jobb hangerőcsatornára is logolja a hangerőváltozást), és ez bezavar a read line parancsnak, ami meg soronként olvasna, így a hangerő nem frissül a panelen. Próbálkoztam, hogy head -n1 pipe-olást iktatok közbe, az se segített. Próbálkoztam grep -m1 kapcsolóval, de az se segít.

The world runs on Excel spreadsheets. (Dylan Beattie)

Ááá, megvan! Kellett a grep-nek a --line-buffered kapcsoló, így már működik a megoldásod:
pactl subscribe | grep --line-buffered sink | sed 'N;s/\n/,/'

Enélkül a kapcsoló nélkül csak 4096 bájtonként írogat a grep kifelé, előtte csak bufferbe gyűjtöget. Ez általában nem gond, mert csak egyszer futtatja az ember, és nem folyamatos pipe-ban eteti. Sőt, kiderült, hogy még a sed se kell, nem zavarnak be a dupla sorok, ha van ez a line-buffered kapcsoló. Jó tudni, mert még sose kellett.

The world runs on Excel spreadsheets. (Dylan Beattie)

Még egy pár gondolat, nem a shellszkriptes részéhez, hanem a lemonbar-hoz. Szerintem nem érte meg. Minimalistább, mint egy polybar, de cserébe nehezebb konfigolni, script kiddie-nek kell hozzá lenni, fontkezelése korlátos. Most, hogy így be van konfigolva végre (awesome font-os ikonokat nem tudtam még úgy összehozni, hogy függőlegesen jól legyenek pozicionálva), összesen eszik 20 MB körül a memóriából. A polybar evett 25-27 körül, de cserébe sokkal szebbre bekonfigolható, könnyebb is a konfigolása, mivel sok kész modul van hozzá, amik trükközés nélkül, épp úgy CPU terhelés nélkül ki tudnak mindent jelezni.

Most is bejött az, hogy a minimalizmusnak megvan az a foka, ahonnan nem éri meg. A dwm-nél is ezt éreztem. Oké, minimalista, de mire az ember hozzáadja a szükséges patcheket és billentyűkombókat, bekonfigolja a paneljét, a végén majdnem ott van memóriafogasztásra, mint egy bspwm lemonbar-ral és sxhkd-vel, cserébe a dwm elég korlátos, míg a bspwm-nek van rendes szerver-kliens socket protokollja, amin keresztül lehet üzengetni neki bspc-vel (és így bármilyen szkriptnyelven lehet konfigolni akár még menet közben is, újraindítás nélkül), támogat EWMH protokollt, aminek mentén xdotool-lal és hasonlókkal is távirányítható, plusz a multimonitor-támogatása is jobb (jó, ezt a részét nem használom). Cserébe alig eszik pár megával többet, de az egész sokkal rugalmasabb. Ilyen kevés MB különbözet még egy nagyon gyenge gépen sem éri meg spórolni szerintem.

Gentoo-val szintén ugyanez volt a bajom. Ki lehet vele hagyni a sysmted-t, initramfs-t, meg le lehet spórolni pár függőséget, pár MB RAM használatot, de az egésztől nem lett gyorsabb a gép, csak ez ember forráskódot pörgettyűzik órákon át, nyereség meg már nincs rajta több egy Arch-hoz, Void-hoz képest, cserébe még néhol lassabb is. Linux from Scratch-ról ez még hatványozottabban elmondható.

Emiatt ezt a lemonbaros konfigolást kicsit felesleges körlefutásnak érzem. Nem teljesen azért, mert mégis csak minimalistább, kevesebb a függősége, bármilyen rendszeren könnyebb leforgatni forráskódból (ez pl. számít BSD-ken), plusz most már hogy jobban tudom konfigolni, ugyanezt a tudást a dwmbar-ra és dzen2-re is át lehet vinni. Plusz a szkriptekről, grep-ről, stb. is tanultam egy csomó érdekes dolgot.

The world runs on Excel spreadsheets. (Dylan Beattie)