HTML

Bagoj úr blogja

Kíváncsi Bagoj befigyel a Linux belsejébe, illetve különféle Linux terjesztéseket próbál ki. Ha jó napja van, scriptet ír Neked.

Friss topikok

Újabb kernel siralmak

2009.06.17. 14:09 bagoj ur

Rövidke post (emlékeztetőül saját magamnak is) arról, hogy még a 8.10-es (Intrepid) Ubuntuval szórakoztam az intel-féle async kernel változattal, de nem jutottam igazán sok mindenre. Erről el is kezdtem egy írást decemberben, majd folytattam januárban, de mivel már annyi minden változott azóta, nem látom értelmét, hogy komolyan befejezzem a dolgot. Hiszen azóta kiderült, hogy egy probléma miatt a 2.6.30-as előtti kernellel nem is érdemes játszani ilyen async dolgot. Ezt teljesen alátámasztja, hogy decemberben az async kernel nem bootolt gyorsabban egy fikarcnyival sem (nem is értettem). :)

Anno annyit játszottam, hogy Arjan van de Ven útmutatása alapján letöltöttem a patch-et, de nem ment fel a 2.6.27-es kernelre. Így fogtam magam és végignéztem a kérdéses fájlokat a kernel forrásban, illetve átírtam a megfelelő helyen a kódokat. Ekkor készítettem is egy patch-et, amivel a 2.6.27 megpatch-elhető lett volna, de azóta egy merevlemez meghibásodáson is túl vagyok (ja majd erről írok is), és akkor nem mentettem el a patch-et. Mivel meg akartam ragadni az alkalmat, hogy leírjak ezt-azt a diff és a patch működéséről, csak röviden a lépések, hogy el ne veszítsem:

diff -uNr linux-source-2.6.27 linux-source-2.6.27-async > 2.6.27_async_fastboot.patch

Az Ubuntu 2.6.27-9-generic kernelének patch-elése:

- A patch bemásolása a /usr/src alá
- belépés a linux-source-2.6.27 könyvtárba
- patch -p1 < ../2.6.27_async_fastboot.patch

A patch egyébként annyit változtat a kernelen, hogy a rendszerhívásokat nem egymás után hívja, hanem mindegyiknek egy egyedi azonosítót, egy sequence cookie-t ad, és a kernel, mielőtt globális hatású műveletet hajtana végre, ellenőrzi hogy minden előző aszinkron meghívott rendszerhívás lefutott-e. De a globális műveletek között ezek "szabadjára vannak eresztve", párhuzamosan futhatnak és elméletben nem okozhatnak zavart. A kernel fejlesztői listán éppen az "elméletben" kitétel miatt mentek a viták...

A lényeg, hogy most már tudom, miért nem jártam én sikerrel - a kernel bebootolt gond nélkül, csak éppen nem gyorsabban, egy fikarcnyival sem.

Mivel már a 2.6.30-assal lehet próbálkozni, fogok is valamikor, rövid távú terveim:

1. Egy szkript készítése, amely legenerálja a kernel konfigot az éppen aktuális betöltött modulok alapján, majd készít egy kernel .deb csomagot. Ez nem initrd-s lesz, de az initrd csak arra kell, hogy kernel modulokat töltsön be, és mivel bele lesz minden fordítva a kernelbe, ezért nem szükséges. Bootsplash nélkül én tudok élni.

2. Ha jól működik a dolog, letöltöm a 2.6.30-as kernelt és azzal is gyártok egy csomagot a Jauntyhoz.

Ennél többet sokkal nem tehetek pillanatnyilag. Az világos, hogy az X-et kell minél gyorsabban elindítani. Ehhez kell legyen alapvető hálózati támogatás, legalább localhost, kell egy hosztnév, a framebuffer meghajtó, és persze írható fájlrendszer. Szóval lehet játszani, hogy futtatok egy saját boot szkriptet, ami beállítja a localhost-ot, meghívom az udev-et és rögtön az X-et. Az ilyenek, mint pl. bluetooth, maradhatnak későbbre.

Mindenesetre ezek a tervek. Hogy ebből mit tudok megvalósítani, ez csak a szabadidőtől függ... sajnos a múltkor beígért notebook-ot nem kaptam meg még, és a munkás notimat érthető okokból csak korlátozottam merem barmolni. :-)

Szólj hozzá!

Címkék: linux fordítás notebook x ubuntu kernel aszinkron 8.04

A nap kérdése: miért nincsenek különbség-csomagok?

2009.06.04. 11:10 bagoj ur

Nézegetem a 9.04 mai napi letöltés-adagját. Nekem természetes, hogy ilyenkor rászánom az időt, és megnézem, hogy mit írnak a changelogba, illetve a biztonsági frissítések hátterének utánanézek.

Igazából mellékes a téma, de mégis érzem a szépítés részét az Ubuntunál - ugyanis a CUPS frissítése úgy jött le, hogy "SECURITY UPDATE: Remote denial of service via ...", ha a Secunia.com-on nézem, ott már többszörös hibákról, és távoli kódfuttatásról is beszélnek a DOS-on kívül. A CUPS oldalán is 3 biztonsági hiba javításáról beszélnek. A Canonical már nem érezte fontosnak, hogy a DOS támadáson kívül jelezze a másik két - egyébként közepesen kritikusnak jelölt - hibát. Hát ezért nézek én utána ezeknek a dolgoknak... :-(

A lényeg, folytatván a CUPS csomaggal, hogy azt nézem, a változtatáshoz, ami lényegében minimálisnak mondható, le kell tölteni a következő csomagokat:

  • cups - ~2,1M
  • cups-bsd - 35 kb
  • cups-client - 112 kb
  • cups-common - 1 Mb
  • libcups2 - 169 kb
  • libcupsimage2 - 50 kb

Összesen: 3,4 Mb

Összesen 3-4 Mb nem a világ, viszont látván a patch-ek méretét, amiket a hibajavításhoz készítettek, kicsit összehúztam a szemöldököm: arányaiban közel ezerszeres a letöltendő. Miért foglaljuk ezzel a sávszélességet?

Gondoltam, csak egyetlen csomagnál ("cups") maradva összehasonlítom az 1.3.9-es és az új, 1.3.10-es csomag tartalmát, hogy egyáltalán mi az, ami változott? Mivel az 1.3.9-es nem volt már meg .deb formában, ezért a dpkg -L paranccsal kiírattam, hogy milyen fájlokból áll a fájlrendszeremen, és ezeket a fájlokat (ugyanabban a struktúrában, ahogy a fájlrendszerben van) lemásoltam egy alkönyvtárba:

for i in `dpkg -L cups`; do TMP=$(echo $i | sed 's_/__'); mkdir -p `dirname $TMP`; cp "/"$TMP $TMP; echo $i; doneA dpkg -L cups tehát egy listát ad a másolandó fájlokról, ezeken végigmegyek, egy átmeneti változóba belerámolom úgy, hogy a legelső perjelet leszedem (így mondjuk a /usr/share-ből usr/share lett), létrehozom a könyvtárat teljes struktúrával (-p paraméter), és belemásolom a /usr/share/.../fájlnevet a usr/share/.../fájlnév alá.

Az új csomaggal egyszerűbb a helyzet, egy apt-get -d install cups parancs csak letölti, de nem frissíti a csomagot - ilyenkor a /var/chache/apt/archives könyvtárba kerül. Megnyitottam a Midnight Commanderrel és kimásoltam belőle a fájlokat egy másik alkönyvtárba. Ezután már csak darabonként össze kellett hasonlítani:

for i in `find .`; do TMP=$(echo $i|sed 's/.//'); if [ -f $i ]; then  diff -qN ../139/$TMP $i; fi; done

(A diff tud rekurzívan is összehasonlítani, de előtte már szórakoztam vele, az if-fel kizártam a könyvtárakat, és mivel már az előbb így építettem fel a dolgot, nem akartam újraírni. Működik.) A változott fájlok listája (és méreteik):

  • /usr/share/man/man8/cupsd.8.gz - 1047
  • /usr/share/man/man8/cups-deviced.8.gz - 884
  • /usr/share/man/man8/cups-driverd.8.gz - 1701
  • /usr/share/man/fr/man8/cupsfilter.8.gz - 1012
  • /usr/share/man/fr/man8/cupsd.8.gz - 1198
  • /usr/share/man/fr/man8/cups-deviced.8.gz - 1067
  • /usr/share/man/fr/man8/cups-driverd.8.gz - 1976
  • /usr/share/man/fr/man8/cups-polld.8.gz - 880
  • /usr/share/man/fr/man5/cupsd.conf.5.gz - 4713
  • /usr/share/man/fr/man5/subscriptions.conf.5.gz - 1392
  • ./usr/share/man/fr/man5/printers.conf.5.gz - 1419
  • ./usr/share/man/fr/man5/mime.convs.5.gz - 1009
  • ./usr/share/man/fr/man5/mailto.conf.5.gz - 1042
  • ./usr/share/man/fr/man5/cups-snmp.conf.5.gz - 1425
  • ./usr/share/man/fr/man5/classes.conf.5.gz - 1377
  • ./usr/share/man/fr/man5/mime.types.5.gz - 1498
  • ./usr/share/man/fr/man7/backend.7.gz - 2567
  • ./usr/share/man/fr/man7/filter.7.gz - 2437
  • ./usr/share/man/man5/cupsd.conf.5.gz - 3989
  • ./usr/sbin/cupsd - 400584

Összesen 423 kbyte. És ez csak akkor, ha nem a bináris különbségeket, hanem az összes megváltoztatott fájlt egyszerre szállítanák. Mi van, ha csak a különbségeknek kéne lejönni?

xdelta

Van egy kis program a bináris különbségfájlok készítésére és kezelésére, ez az xdelta névre hallgat. Ha elkészítjük az előbbi fájlokról a bináris diffeket, meglesz hogy mekkora különbséggel számolhatunk:

for i in $(echo "./usr/share/man/man8/cupsd.8.gz ./usr/share/man/man8/cups-deviced.8.gz ./usr/share/man/man8/cups-driverd.8.gz ./usr/share/man/fr/man8/cupsfilter.8.gz ./usr/share/man/fr/man8/cupsd.8.gz ./usr/share/man/fr/man8/cups-deviced.8.gz ./usr/share/man/fr/man8/cups-driverd.8.gz ./usr/share/man/fr/man8/cups-polld.8.gz ./usr/share/man/fr/man5/cupsd.conf.5.gz ./usr/share/man/fr/man5/subscriptions.conf.5.gz ./usr/share/man/fr/man5/printers.conf.5.gz ./usr/share/man/fr/man5/mime.convs.5.gz ./usr/share/man/fr/man5/mailto.conf.5.gz ./usr/share/man/fr/man5/cups-snmp.conf.5.gz ./usr/share/man/fr/man5/classes.conf.5.gz ./usr/share/man/fr/man5/mime.types.5.gz ./usr/share/man/fr/man7/backend.7.gz ./usr/share/man/fr/man7/filter.7.gz ./usr/share/man/man5/cupsd.conf.5.gz ./usr/sbin/cupsd"); do TMP=$(echo $i|sed 's/.//'); xdelta delta ../139/$TMP $(basename $i)".diff" $i; done

Bocs, kicsit ronda lett, de az egyszerűség kedvéért felsoroltam a fájlokat, amit normál esetben egy fájlból olvasok fel.

A végeredmény: 54,768 byte. A letöltött, 1.3.10-es csomag mérete: 2,134,000 byte. Tehát elég lett volna leszedni a csomag

2,56%

-át, és ugyanazt a megoldást elértük volna az xdelta segítségével.

A másik, ami ma lejött, az evolution - 6,4 Mb-ot töltöttem le, azt nem számoltam ki hogy a mennyi helyett, de biztos vagyok benne hogy ennél is ergyább eredmény jönne ki, nézegetvén hogy mit patch-eltek a srácok.

Szóval, sok kicsi sokra megy. Mondjuk ha ezt a CUPS frissítést letöltik egymillióan, az kb. 1,9 Terrabyte felesleges forgalom! Az Internet forgalom 90%-a úgyis a spamekre megy el, miért nem becsüljük meg kicsit a maradékot?

Szóval tök jó lenne, ha a csomagkezelést átalakítanák ilyen xdelta-szerűre, és mondjuk csak a főverziókból jönne le teljes csomag (vagy ha akarom). Egyébként meg (ha akarom), csak a különbségek. A bináris patch-elés is rövidebb ideig tart egyébként az xdelta-val, mint leszedni a régi csomagot és feltenni az újat: 1,088 másodperc volt az xdelta patch <patchnév> <eredeti fájl> parancssal megcsinálni (az apt-get kb. 3-4 percet szöszölt - természetesen le kell futtatni ilyenkor szkripteket is, de azt is meg lehetne csinálni az xdelta után is).

A kérdés tényleg az, hogy miért, miért, miért?

7 komment · 1 trackback

Címkék: linux patch csomag ubuntu sávszélesség bináris deb diff xdelta

Bagojból is lehet vándormadár

2009.06.01. 23:53 bagoj ur

Tegnap jó hír érkezett: valószínűleg fogok kapni kölcsönbe, de hosszabb távra egy laptopot. Azt nem tudom, pontosan miféle, de az eddigi vasaimnál papíron biztosan jobb lesz. Ebben az a jó hír, hogy tudok egy kicsit majd több dologgal kísérletezni, ugyanis nem borult el annyira a tudatom, hogy azon a gépen próbálkozzak mondjuk fájlrendszer tesztekkel (nem, ilyet nem fogok csinálni, csak vicceltem!), amelyiken a napi munkámat is végzem. :-) Szóval eddig kötve volt a szárnyam, de végre nekieshetek az Ubuntus bootos ötleteimnek!

A címhez kapcsolódóan: Az írások számát tekintve már-már elkezdtem javuló tendenciát mutatni a márciusi mélyponthoz képest, amikor elérkezett a szabadság ideje. Szóval két hétig még gép előtt sem leszek, sőt kis hazánkat is elhagyom, tehát nem a június lesz az extra post számot termelő hónap (aztán ki tudja). Bocsiii :-(

Visszatérek.

Szólj hozzá!

Netsurf - újabb pici böngésző

2009.05.23. 03:31 bagoj ur

Mivel közismerten gyík hardverrel rendelkező gépeim vannak, nekem nem mindegy, hogy milyen böngészőt használok. A Firefox nagyon kényelmes, kézreáll és óriási tudása van a kiterjesztésein keresztül, de én folyton keresgélek olyasféle kis böngészőt, ami valamelyik menő renderelő motort használja (Gecko vagy Webkit, hogy kompatíbilitási gondjaim ne legyenek), de a körítés (és ehhez kapcsolódóan a memóriafogyasztás ill. gyorsaság) kisebb.

Próbáltam az Epiphany-t, ami nagyon patent csak eléggé kötődik a Gnome-hoz, elég sok beállítása csak a gconf alól érhető el. Ráadásul a megnyitott tab-okat csak akkor tudja elmenteni, ha összeomlott. :-( Ez teljesen érthetetlen hiszen akkor kéne legjobban amikor rendesen léptem ki, az ezt támogató kód pedig benne van a programban.

A másik a Kazehakase, szintén Gecko motorral - az sajnos, mint kiderült, ugyanolyan lassú mint a Firefox és az Adblock technológiája eléggé gyenge (fájlba kell felsorolni a meg nem jelenítendő dolgokat, és ráadásul akkor is letölti, csak nem mutatja meg; így az oldal nem fog gyorsabban megjelenni). Nekem sokszor össze is omlott sok tab-bal. Amúgy jó dolgok vannak ebben a böngészőben, talán eljutnak majd oda hogy a Firefox-szal összevethető lesz.

Az újabb ígéretes versenyző tehát a Netsurf Browser. Nem is olyan régen adtak ki egy új (2.0) verziót egy év fejlesztés után, gondoltam ezt meg kell lesni.

Nem mondom, hogy túl egyszerű. Azt sem, hogy megérte.  :-)

Elsőként felraktam a subversion csomagot és leszedtem a teljes, aktuális forrást, mivel a 2.0-s verzió csak forrásként érhető el, és ha csak simán a .tar.gz-t töltöm le, abban nincs egy rakás library, ami kell a fordításhoz. Az egész trunk-öt leszedve "minden" szükséges megvan (látván a szükséges csomagok listáját, távolról sem mondanám teljesnek; ezek csak a netsurf fejlesztők által fejlesztett libek). Mielőtt nekikezdünk, készítsünk neki külön könvytárat mert sok alkönyvtár lesz:

svn co svn://svn.netsurf-browser.org/trunkHadd szaladjon. Ezek után van egy rakat fájlunk, de ez még nem elég. Lassanként sikerült kitapasztalnom, a fordításhoz milyen libeket kell leszedni (a fordítás után a nagy részét törölni lehet, nem kell megijedni):

sudo apt-get install zlib1g-dev libpng12-dev libxml2-dev gperf debhelper gettext html2text intltool-debian libatk1.0-dev libcairo2-dev libexpat1-dev libfontconfig1-dev libfreetype6-dev libglib2.0-dev libgtk2.0-dev libice-dev libmail-sendmail-perl libpango1.0-dev libpixman-1-dev libpthread-stubs0 libpthread-stubs0-dev libsm-dev libsys-hostname-long-perl libx11-dev libxau-dev libxcb-render-util0-dev libxcb-render0-dev libxcb-xlib0-dev libxcb1-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxft-dev libxi-dev libxinerama-dev libxrandr-dev libxrender-dev po-debconf x11proto-composite-dev x11proto-core-dev x11proto-damage-dev x11proto-fixes-dev x11proto-input-dev x11proto-kb-dev x11proto-randr-dev x11proto-render-dev x11proto-xext-dev x11proto-xinerama-dev xtrans-dev libglade2-dev liblcms1-dev comerr-dev libcurl4-gnutls-dev libgcrypt11-dev libgnutls-dev libgpg-error-dev libidn11-dev libkadm55 libkrb5-dev libldap2-dev libtasn1-3-dev libssl-dev lemon librsvg2-dev re2c libcurl4-openssl-dev libjpeg62-dev libmng-devSzép kis mennyiség. Ezek után haladjunk be sorban az alábbi könyvtárakba, és adjuk ki mindenütt a szokásos

make
sudo make install
parancsot, kivétel a libharu, ahol csak egy make-et tudunk kiadni, az elkészült kódot a prefix-native/lib illetve prefix-native/include alól kell a /usr/local/lib és /usr/local/include alá bemásolni. De mindent csak sorrendben! Tehát:

  • libnsbmp
  • libnsgif
  • libsvgtiny
  • libharu
  • hubbub
  • libwapcaplet
  • libparserutils
  • netsurf

Utóbbinál a Makefile.default-ot másoljuk át Makefile.config-gá, mielőtt fordítani kezdünk. Én a netsurf könyvtárban nem nyomtam make install-t, onnan indítottam. A többi könyvtárra nekem nem volt szükség, nem tudom, hogy kellenek-e.

Ha elkészült a nagy mű, akkor még foglalkoznunk kell azzal, hogy a függvénykönyvtárak, azaz a libek a /usr/local/lib alá készültek el, az LD_LIBRARY_PATH (ez a függvénykönyvtárak elérési útja) ezt nem tartalmazza. Mivel én nem nyomtam make installt, ezért a netsurf alkönyvtárban így indítottam el:

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/ ./netsurf

Az eredmény fél másodpercen belül látható. Viszont nézzük, hogyan küzd meg egy index.hu-val:

Oké, oké, rohadtul igazságtalan vagyok, rengeteg ilyen oldalt mutathatnék, hiszen JavaScript támogatás, mint olyan egyáltalán nincs. Természetesen flash támogatásról is csak ábrándozhatunk. Következésképpen a látogatható oldalak száma manapság erősen limitált. Van egy részleges 2.1-es CSS támogatás, illetve 4.akárhányas HTML és itt megáll. Lássuk ennek előnyét, megnyitva ugyanazon oldalakat a Firefox 3.0.10-ben is, a memóriafoglalás így alakul:

Firefox: 334M
netsurf: 107M
 

És végülis a gmailnak van Javascript-mentes változtata, be is tudja tölteni. És, mint megtudtam, még a Google Maps is megy Javascript nélkül!

Ettől függetlenül ez a JS-dolog nekem nem esett le előtte, ezért egy kis csalódással kell megállapítanom, hogy vagy valamit félrenéztem a fordítás során, vagy ez a böngésző azért gyors mert keveset is tud (például nem lehet keresni az oldalon belüli szövegekre stb. pár alapvető dolog nincsen meg). Ettől függetlenül egész korrekt; van letöltésvezérlője, támogat proxykat (még NTLM-en is!), SSL oldalakat és ha elfelejtettem volna mondani, természetesen multitabos. És van benne adblock, bár nem jöttem rá, hogyan működik.

A kérdés, hogy miért állnak neki valakik egy ki tudja, hanyadik böngészőt gyártani? Nos, ki tudja mi lesz belőle, tíz év múlva lehet vezető böngésző, és erről is szól az open szósz. Most viszont napi használatra alkalmatlan.

2 komment

Címkék: linux fordítás böngésző alkalmazások csalódás netsurf

Még rondább, de frankó - SED, a Stream EDitor

2009.05.22. 11:22 bagoj ur

Ismét egy kis parancssoros bugizás - természetesen egy személyes problémából indultam ki, de ennek nyomán sikerült a sed-be is egy kicsit beletanulni. Pontosabban, ez olyan hogy ha használom, akkor persze minden világos, ha egy darab ideig nem használom, akkor pedig vissza tudok jönni saját blogomra okosodni. :-)

Ma a sed használatával ismerkedünk meg, méghozzá konkrét problémákon keresztül. Fogjuk látni, hogy a sed-del sok mindent meg lehet csinálni, amire vannak amúgy célparancsok is a UNIX/Linux/*BSD világban. Gondolok arra, hogy ugyanaz a feladat, amire első gondolat alapján a grep-et használjuk, megoldható ugyanúgy sed-del is például (de valószínűleg a múltkor emlegetett awk-kal is). Tehát lényegében elég egy parancsot kimerítően megismerni az összes lehetőségével, de valahogy én sem ezt teszem, vezeti a megszokás a kezemet - ha egy fájlban szűrni kell, grep-elek, ha a soron belül cserélni, akkor sed utasítást faragok, ha pedig a sztringeket mezőként kell kezelni, csereberélni vagy szimplán kiíratni; akkor az awk-t. Ebből már talán kiderült, hogy a sed fő funkciója nálam az, hogy egy soronként felolvasott fájlban sztring cseréket végezzen el; és a sed a reguláris kifejezések nagy bajnoka, nekem elhihetitek.

A neve egy rövidítés: "My name is Ed, Stream Ed", hogy egy béna szóviccet mondjak. Ettől függetlenül egy kis zseni:

Minden páros vagy páratlan sor kiíratása egy text fájlból

Elkövettem egy apró bakit - szimultán futott két példány egy mérést végző programból, és elfelejtettem külön fájlba irányítani a kimeneteket. Ott volt a fájlban a mérés eredménye, de a páratlan és páros sorokban másra vonatkozott. A misszió ezek szétszedése külön fájlokba. Azt hiszem, a Windows alatt elvéreztem volna. Itt pedig:

bagoj@tarantula:~$ sed -n '1~2p' eredetifajl > paratlan_sorok.txt
bagoj@tarantula:~$ sed -n '2~2p' eredetifajl > paros_sorok.txt
Nyilván tartozom egy magyarázattal. :-)

A sed működése

Tehát a sed részére meg kell határozni két dolgot:

  1. Mi az, amivel valamit kezdeni akarunk
  2. Mit akarunk vele kezdeni

Néha az első feladat a nehezebb. Megadhatunk reguláris kifejezést, vagy meghatározhatunk sorokat. A regexp megadása a szokásos /regexp/ néven lehetséges, például a /^$/ az üres sorokra illeszkedik (^  a sor eleje, $ a sor vége, közötte nincs semmi); a /.*$/ bármire (üres sorokra is) és ezt most tényleg estig sorolhatnám. Ami viszont poénos, meghatározhatunk egy teljes részt a fájlban a kezdő és záró regexp-ek segítségével:

/start/,/stop/

Itt a "start"-ot tartalmazó sortól a "stop"-ot tartalmazó sorig fog menni.

A range meghatározása sorok kijelölésével már rafináltabb, és ezt alkalmaztuk az előbb is:

1,10 -> Vesszővel elválasztva simán az 1 - 10-es sorokat határozzuk meg
50,$ -> Az ötvenedik sortól a fájl végéig
1~10 -> Kezdjük az első sorral, és 10-es lépésközt használunk, azaz minden tizediket íratjuk ki
A legtutibb a regexp és a sor meghatározás kombinációja:

1,/start/

Mókás, nem? Az első sortól az első, "start" sztringet tartalmazó sorig fogunk haladni.
 

Jöhet a második rész, a "mit kezdjünk vele". Erre a sed-ben egybetűs utasítások vannak. Népszerűbbek:

a,i = sor beszúrása a range elé, illetve mögé
p = print, tehát sima kiíratás
s = substitution, azaz csere, -->  s/mit/mire/
d = delete, törlés
y = átalakítás, úgy működik mint az s, csak mást csinál
= = Sorszám kiírása (igen, az egyenlőségjel)
n = next (következő sorra ugrik)
q = quit (kilép)

Van még nagyon sok parancs, tud fájlból olvasni, fájlba írni stb. de ezeket most kihagynám. :-) A sedről nyilván könyveket lehetne írni.
 

Még egy apróság, egyetlen kapcsolót érdemes megtanulni, ez a "-n", amit az első példában is leírtam. A sed ugyanis alapértelmezésben kiírja az összes sort. Ha mi csak bizonyos sorokat akarunk kiíratni, a -n paramétert kell használni hogy ne írjon ki semmit, és a p paranccsal íratunk ki.

Konkrét használat

Rakjuk most össze a range meghatározásokat (=mivel) a parancsokkal (=mit csinálunk). Rövid példák az előzőek felhasználásával:

sed -n '1,10 p' filenév -> Kiírja az első 10 sort
sed -n '1,/start/ s/alma/korte/g p' -> Az első sortól a "start"-ig lecseréljük az "alma"-t "korte"-re, és az eredményt kiírjuk. A 'g' parancs a 'p' előtt azt jelenti, hogy ha egy soron belül több egyezés van, akkor mindent cseréli. Egyébként csak az első előfordulást cserélné!

Figyeljük meg, hogy mi van, ha a -n kapcsolót és a végén a 'p' parancsot elhagyjuk! (Ekkor csak a megadott sorokban cserél, de a fájl teljes tartalmát kiírja - a megváltozott sorokat természetesen megváltoztatva):

sed '1,/start/ s/alma/korte/g'
Remélem, kezdtek Ti is belendülni... tegyük fel hogy van egy logfájl, amiben szeretnénk két meghatározott dátum között listázni. Ezt grep-pel nem igazán lehet megoldani, hiszen be kellene írni a két időpont közötti összes egyező dátumot. A logfájl a szokásos módon néz ki, és a /var/log/messages alatt keletkezik:

May 15 06:26:57 hostname Üzenet
May 15 06:26:58 hostname Üzenet2
Egy 15Gb-os napi fájlban nehézkes grep-pel nekiállni, ha tudjuk az időszeletet. Nekünk viszont a 08:00 és 08:40 között eltelt idő kell. Írjuk hát ezt:

sed -n '/May 15 08:00/,/May 15 08:40/p' /var/log/messages

A kimenetet pedig átirányíthatjuk más sztring feldolgozó parancsokba.

Néhány további példa:

sed '50,100 d' -> Töröljük a fájlból az 50 - 100. sorokat (és a maradék fájlt kiíratjuk).
sed -n '50,100 !p' -> Lényegében ugyanaz, az 50 - 100. sorokat nem írja ki, a többit igen

sed 'n;d' -> Minden második sor törlése. Könnyen el tudjuk képzelni a felsorolt parancsok alapján: Az n-nel lép a következő sorra, és a d-vel kitörli.

Néhány örökzöld hasznos:

sed 's/$/\r/' -> UNIX to DOS (Minden sor vége elé beszúrunk egy LF kódot)

sed 's/.$//' -> DOS to UNIX (feltéve, hogy mindegyik sor DOS-os! A sorvége előtti karakter töröljük, így ha valamelyik sor nem DOS-os, akkor ténylegesen törölhet egy hasznos karaktert!)

sed 's/\x0D$//' -> A bonyolultabb DOS to UNIX. A sorvége előtti 13-a s kódú karaktert (/r) töröljük

sed 's/[ \t]*$//' -> A szöveg végéről a felesleges whitespace (szóköz, tab-ok stb.) eltávolítása

sed 's/^[ \t]*//;s/[ \t]*$//' -> A szöveg elejéről és végéről a felesleges whitespace leszedése (én pl. programkódok diff-elése előtt ezt meg szoktam csinálni, mivel van az úgy hogy a behúzásokat átcserélem; és mivel ezek a sorok változtak, ezért azokat is kiírja a diff bár nekem az nem hasznos)

sed 's/alma/korte/2' -> Már írtam a 'g'-ről, ami minden előfordulást cserél. Ez itt csak a második előfordulást cseréli egy soron belül!

sed '/^$/d' -> Ahogy már írtam, törli a fájlból az üres sorokat
Visszahivatkozás

 Természetes, hogy szükség van erre is. Ez ugye annyi, hogy vissza tudunk hivatkozni arra a (változó) tartalomra, amire a regexp vonatkozik. Példa, hogy minden szám mögé akarunk egy nullát írni, azaz 10-zel megszorozzuk őket:

sed 's/[0-9]*/&0/g'

A '&'-jel a visszahivatkozás, tehát visszaírja ugyanazt a számot, amire a mintaillesztés megtörtént, majd mögé biggyeszt egy 0-t.

Működnek a \1 - \9 -ig tartó számozott visszahivatkozók is, ha egyszerre több szövegrészre akarunk matchelni. Egy kicsit bonyolultabb példán mutatom be, hogy mondjuk van egy fájl, amelynek az elején az óra:perc formátum van, amit szeretnénk megfordítani valami miatt. Ekkor illesztünk az órára és a percre, és fordított sorrendben kiírjuk őket. Színekkel jelöltem az összetartozó dolgokat, hogy mi mire vonatkozik.

18:35 Párisba tegnap beszökött az Ősz.
18:36 Szent Mihály útján suhant nesztelen,
18:38 Kánikulában, halk lombok alatt
18:44 S találkozott velem.

sed 's/^\([0-9]*\)\:\([0-9]*\)/\2:\1/'

A félkövérrel jelölt részek tartoznak a sed-hez. :-) Tehát elkezdünk egy s parancsot, jön egy / elválasztójel, majd a caret (^), azaz a sor eleje. A piros rész illeszkedik minden számra, ami egy kettőspontig tart. A teljes piros blokk feloldása:

[0-9] -> egy darab bármilyen számra illeszkedik
[0-9]* -> nulla vagy egy vagy több számra illeszkedik
([0-9]*) -> nulla vagy egy vagy több számra illeszkedik ÉS megjegyzi visszahivatkozásként
\([0-9]*\) -> Mivel a zárójelek speciális karakterek, escape-elni kell azaz visszapert írunk elé

A kettőspont is különleges, tehát az elé is kerül egy '\'

A mintaillesztés után jön megint egy '/'-jel, ami bolddal van. Utána jön a \2:\1, ami kiírja a második illeszkedő karaktersort, egy kettőspontot és az elsőnek illeszkedő karaktersort. Remélem, világos.

Elválasztó jelek

Szerintem sokan nem ismerik a következő, igen szuper kis módszert. Tehát azt láthattuk, hogy a legtöbbet használt 's' (helyettesítés) utasításban az elválasztó jel a '/', tehát

s/alma/korte/

Mi van, ha mondjuk egy fájlnevet kell teljes elérési úttal cserélni? Dolgozhatunk úgy is, hogy escape-eljük a sok perjelet:

sed 's/\/home\/bagoj\/bin/\/usr\/bagojne/'Ugye, milyen ronda? :-) Emiatt sokan utálják a sed-et, és nehéz is olyan sort írni, ami minden esetben működik. De elválasztójelnek használhatjuk a _, : és | jeleket is!

sed 's:/home/bagoj/bin:/usr/bagojne:g'

Sokkal jobb, nem? Szinte a zsenialitás határát súrolja...

Bár nem volt szándékomban egy átfogó, részletes, egymásraépülő anyagot összehozni, csak összedobáltam ami eszembe jutott, remélem ezzel mégiscsak segítettem. Jó "szedálást"! :-)

1 komment

Címkék: bash parancssor

süti beállítások módosítása