pondělí 26. prosince 2011

Sedy, lehy, regulární výrazy 1

sed, awk, grep a jiné pěkné cli nástroje pro zpracování textu umožňují použití regulárních výrazů, což jsou takové masky, kterými můžete definovat řetězec, který v textu hledáte. Základy znám, ale každou chvíli objevím něco nového, co mi uniklo, protože zas tak svědomitě jsem to nestudaval. A tak bych chtěl začít seriálek, ve kterém bych si tyto objevy zapisoval.

Tak například dneska jsem se opět připletl k něčemu, co mě donutilo trochu posunout znalosti. Šlo o parsování xml dokumentu pomocí sedu a tím zajímavým je vytípnutí výrazu mezi dvěmi uvozovkami. Vzhledem k tomu, že regulární výrazy jsou od přírody žravé a tak těžko vytípnete řetězec v uvozovkách něčím jako toto: var=".*" , když je na řádku těch uvozených výrazů více, potřebujete něco lepšího. Pomohou htanaté závorky, kterými je možné definovat povolené znaky, ale pomocí znaku ^ (stříška), je možné výběr invertovat a definovat tak zakázané znaky. Proto uspějete s následujícím výrazem:

echo '<location altitude="307" latitude="50.92139" longitude="15.07974" geobase="geonames" geobaseid="3076124" />' | \
sed -n 's/ *<location .*latitude="\([^"]*\)".*/\1/p'

50.92139

Pokud nevíte, kulaté, zpětným lomítkem escapované závorky definují subvýraz, na který můžete dále odkazovat pomocí výrazu \1, a pokud je takových subvýrazů více, jsou číslovány podle výskytu zleva do prava.


neděle 11. prosince 2011

Spouštěcí skript a opět Launcher

Další poznámky z mého bastlení. Občas je před spuštěním aplikace potřeba z shellu nastavit nějaké ty proměnné prostředí. Pokud nemáte pevně dané umístění aplikace, ale znáte pouze její relativní umístění vzhledem ke spouštěcímu sktiptu, může si skript tuto cestu jednoduše odvodit. Je-li ve stejném adresáři, jako aplikace, kterou spouští, může spouštěč vypadat třeba takto:

#!/bin/sh
export UBUNTU_MENUPROXY=
cd "` dirname "$0"`"
./aplikace "$@" &

Proměnná $0, obsahuje řetězec, kterým byl skript volán, může to být například ./Desktop/adresář/aplikace. Příkaz dirname z cesty odstraní vlastní jméno skriptu, a ponechá cestu. Ať už je cesta relativní, vztahující se k aktuálnímu pracovnímu adresáři, nebo absolutní, příkazem cd "` dirname "$0"`", změníte pracovní adresář na ten, ve kterém se nachází skript, ze kterého příkaz voláte. Absolutní cestu pak můžete získat příkazem pwd.

Následující text doplňuje můj předchozí příspěvek Quicklisty - problém se zdvojováním ikon a souvisí právě s tématem spouštěcího skriptu.
Nazvu například pythonní skript aplikace a spouštěcí skript aplikace-spouštěč. Desktopový spouštěč, umístěný v Unity Launcheru, tedy odkazuje na spuštěcí skript, který dále spustí aplikaci a sám chcípne, protože jsem aplikaci nechal spustit na pozadí příkazem &. Stane se to, že si Launcher nedokáže spojit hlavní okno aplikace se skriptem, který spustil a vytvoří pro okno novou ikonu. Tak si říkám "třeba to jen nestihne.." a přidám na konec skriptu sleep 5. Hle, není úplně hloupý, zabralo to. No jo, ale jen pokud spustím aplikaci poklepáním přímo na ikonu. Při spuštění z menu quicklistu, se ikona opět vesele zdvojuje, stejně jako jsem popsal ve výše zmíněném příspěvku. Dále tedy zařazuji základní myšlénku, že když se budou spouštěč i aplikace jmenovat stejně, bude se i proces jmenovat stejně a to by mohlo něco řešit. Samozřejmě je nemůžu mít v jednom adresáři, tak vytvořím podadresář launcher, spouštěcí skript nacpu tam a doplním příkaz pro přesun do nadřazeného adresáře:

#!/bin/sh
export UBUNTU_MENUPROXY=
cd "` dirname "$0"`"
cd ..
./aplikace "$@" &

A sláva, funguje jak má, i bez sleepu. Cairo Dock ikony také nezdvojuje, ale zase registruje pouze první instanci a další vesele ignoruje. Je to zkrátka legrace :)

Zkoušel jsem předtím operovat i s parametrem StartupWMClass, kterým můžete v desktopovém spouštěči určit třídu okna, která k němu patří, ale to v mém případě řešení nepřineslo.