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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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?

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

Ááá, 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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)

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.

A computer is like air conditioning – it becomes useless when you open Windows.” (Linus Torvalds)