Jak dostosować *nixowy terminal do swoich potrzeb.

13 komentarzy

Terminal to jedno z ważniejszych narzędzi wielu użytkowników *nixów. Gdy używa się go często i czerpie się garściami z jego walorów, warto jest go dopasować tak, żeby wziąć maksimum. Wymaga to odrobiny pracy, ale myślę, że warto.

Podstawą podstaw jest czytelność. Jeśli nie mamy dobrze dobranej czcionki, dobrze dobranych kolorów, dużo tracimy. W przypadku terminala, sprawa jest dość prosta, bo czcionką zwykle zajmuje się system operacyjny, ale pozostają jeszcze kolory, które bardzo ułatwiają pracę. Pomijając fakt, że warto ustawić w ustawieniach programu powłoki aliasy, które będą uruchamiać programy (na przykład ls) tak, żeby używały kolorów; warto się zająć też samymi kolorami. Nie zawsze są one dobrze dobrane. Na przykład niebieski jest za ciemny, żółty wygląda brzydko, biały za jasny i takie tam. Na szczęście możemy je przedefiniować w bardzo prosty sposób. Jak zapewne wielu osobom wiadomo, terminal używa 8 kolorów, które nazywają się 0=black, 1=red, 2=green, 3=yellow, 4=blue, 5=magneta, 6=cyan, 7=white. Do zmieniania ich definicji używamy sekwencji ze znakiem "escape". Składnia jest bardzo prosta: ^[]Pxrrggbb, gdzie ^[ jest znakiem escape (można go uzyskać na wiele sposobów, na przykład wywołując cat z przekierowaniem do pliku i wciskając ESC), x jest numerem koloru, a rrggbb jest definicją koloru w rgb, szesnastkowo. Ja na przykład mam następującą definicję:

echo "^[]P0000000 ^[]P1ff0000 ^[]P200ff00 ^[]P3ffff00 ^[]P43030ff ^[]P5ff00ff ^[]P600ffff ^[]P7909090"

Oczywiście nie samym terminalem żyje człowiek. Żyjemy w XXI wieku, mamy X11 i używamy wirtualnych terminali. Mamy tu wiele różnych opcji: Konsole, Terminal, klasyczny xterm czy mój faworyt, urxvt. Oczywiście sam wybór odpowiedniego emulatora terminala to no nie wszystko. Trzeba go jeszcze dobrze skonfigurować. W przypadku tych łatwych programów nie jest to trudne, jednak nie każdemu muszą one pasować. Ja na przykład lubię urxvt i pokażę jak go szybko i sprawnie skonfigurować.

Podstawową konfigurację można przeprowadzić za pomocą linii poleceń (opcja dla mało wymagających), używając takich przełączników jak -bg (kolor tła), -fg (kolor tekstu) i -fn (czcionka). Moim zdaniem jednak to za mało, żeby mieć ładny emulator terminala (poza tym ta metoda jest dobra tylko do wywoływania z menu). Dlatego też polecam grzecznie przejrzeć manuala i zabrać się do pracy (lub skorzystać ze ściągawki poniżej :D).

W przypadku (u)rxvt, konfiguracja odbywa się poprzez wpisanie odpowiednich wartości (tzw. resources, wszystkie można znaleźć w manie) do ~/.Xdefaults (choć może to być jeden z kilku innych, też do wyszperania w manie). U mnie wygląda to tak:

URxvt.background: black
URxvt.foreground: white
URxvt.color0: #dddddd
URxvt.color1: #ff0000
URxvt.color2: #00ff00
URxvt.color3: #ffff00
URxvt.color4: #5050ff
URxvt.color5: #ff00ff
URxvt.color6: #00ffff
URxvt.color7: #ffffff
URxvt.cursorColor: #00ff80
URxvt.cursorColor2: #000000
URxvt.font: -*-courier-medium-r-*-*-25-*-*-*-*-*-*-2
URxvt.mfont: -*-dejavu sans-medium-r-*-*-17-*-*-*-*-*-*-u
URxvt.title: Terminal
URxvt.virtualBell: True
URxvt.loginShell: True
URxvt.scrollBar: False
URxvt.termName: xterm

Sprawa jest dość prosta. Jak widać wszystkie wpisy zaczynają się od URxvt. Wpisy colorn (gdzie 0>=n >=7) definiują kolory (numery analogiczne do tych przestawionych poprzednio); cursorColor definiuje kolor kursora; cursorColor2 to kolor tekstu podświetlonego kursorem; font deklaruje standardowy font; mfont -- font dla znaków unikodu; title definiuje nazwę terminala (skrypty mojego systemu nie rozpoznają rxvt-unicode i produkują nieprzyjemny komunikat przy logowaniu); virtualBell emuluje brzęczyk systemowy; loginShell na true sprawia, że terminal standardowo jest login shellem, a scrollBar włącza pasek przewijania.

Ładny wygląd terminala to ciągle nie wszystko. Może nawet mniej ważna część. Bardzo istotną sprawą jest program powłoki, bo pozwala bardzo przyspieszyć pracę (a nie tylko nie spowalniać, jak w przypadku terminala). Oprócz popularnego w świecie Linuksów Basha mamy do dyspozycji jeszcze kilka godnych uwagi programów powłoki. Od siebie polecę zsh (ze względu na bardzo duże możliwości -- taki fvwm wśród shelli ;p) i tcsh którego konfigurację opiszę.

Na początek jednak krótkie wyjaśnienie czemu tcsh. Mianowicie zsh jest jak dla mnie zbyt rozległy, różnorodność wszelakich opcji trochę mnie przytłaczała. Natomiast bash zdaje się być mało wyrafinowany, mało informacji ma w manie i w necie nigdzie nie znalazłem żadnych ciekawych konfiguracji. Za to tcsh ma całkiem spore możliwości i dobrą dokumentację (całą konfigurację udało mi się zrobić na podstawie mana).

Konfiguracja tcsh to przede wszystkim plik .cshrc (ze względu ma to, że jest tylko rozszerzoną wersją csh). Taką konfigurację można podzielić na trzy części. Zanim zacznę jednak, myślę, że należy zaznaczyć, że ciąg znaków ^[ reprezentuje jeden znak "escape". W przypadku bindkey, wersja dwuznakowa powinna działać, w przypadku echo już nie koniecznie. Pierwszą częścią są zmienne konfigurujące program, ustawiane poleceniem set:

set savehist = 100
set addsuffix
set complete = "enhance"
set echo_style = "both"
set path = ( "/bin/" "/usr/local/bin/" "/usr/bin" "." )
set printexitvalue
set prompt = "%{\033[33m%}%c%{\033[31m%}%%%{\033[37m%} "
set rprompt = "[%T][%j]"
set prompt2 = ">"
set rmstar

Zmienna savehist określa ile kolejnych komend powinno być zapisywanych na dysku (jeśli nie ustawione, pamięta tylko komendy z obecnej sesji). Zmienna addsuffix sprawia, że przy dopasowaniu (tab completion) nazwy katalogu, pojawi się za nią znak / zamiast spacji. Ustawienie zmiennej complete na enhance sprawia, że przy dopasowywaniu nie są rozróżniane wielkie i małe litery, a także kropka, podkreślenie i myślnik nie są rozróżniane. Ustawienie zmiennej echo_style na both sprawi, że polecenie echo będzie rozróżniać opcję -n (brak znaku nowej linii na końcu) i będzie rozpoznawać sekwencje ze znakiem "\". Path chyba jest dość oczywisty, poza składnią typową dla csh. Jak ładnie widać, oprócz standardowych "binów" dodałem sobie bierzący katalog. Zmienna printexitvalue sprawia, że jeśli program zwóci wartość niezerową, csh to zakomunikuje. Zmienna rmstar natomiast sprawia, że zostaniemy poproszeni o potwierdzenie w przypadku wywołania magicznego "rm *". Niestety nie dotyczy to np "rm katalog/*".

Zostały nam jeszcze trzy ważne zmienne ustalające prompt. Jest to jedna z kluczowych rzeczy jeśli chodzi o wygodę pracy z powłoką. Podstawowy prompt składa się z dwóch części, podobnie jak w zsh, wyrównanej do prawej i do lewej. Użyte przeze mnie symbole to: %c (nazwa bieżącego katalogu), %% (czyli procent ;)), %T (czyli godzina w systemie 24-godzinnym) i %j (ilość zadań uruchomionych w tle). Warto również zwrócić uwagę na trochę nietypowy sposób ustawiania kolorów (choć w gruncie rzeczy, dużej różnicy w stosunku do np Basha nie ma). Dla nie wtajemniczonych dopowiem, że % jest używany jako znak zachęty dla nie-roota w csh (tak jak $ w bashu). Na koniec zostaje zmienna prompt2, która definiuje znak zachęty podczas definiowania kolejnych linii pętli foreach i while.

Następną część stanowią definicje skrótów klawiszowych.

bindkey "\t" complete-word-fwd
bindkey "^[[Z" complete-word-back
bindkey "^[[3~" delete-char
bindkey "^A" expand-glob
bindkey "^[[6~" i-search-back
bindkey "^[[5~" i-search-fwd

Nie jest tego dużo, ale potrafi sporo. Po pierwsze, na tab mam tab-completion z tą właściwością, że od razu dopasowuje pierwszą możliwość w przypadku gdy jest ich wiele. Na shift+tab (^[[Z) mam działanie odwrotne do taba (tj. wybiera poprzednie dopasowanie). Działanie delete (^[[3~) chyba jest oczywiste. :) Na ctrl+A (^A) mam rozwinięcie globu do pełnej postaci (wypisze wszystkie elementy pasujące). Na page up (^[[5~) i page down (^[[6~]) natomiast mam ustawione przeszukiwanie historii odpowiednio do przodu i do tyłu. Jest to bardzo przydatne, bo w trakcie pisania, powłoka podsuwa odpowiedzi, którą można zatwierdzić escapem lub enterem lub odrzucić w razie niepowodzenia -- CTRL+G.

Trzecią i ostatnią grupą są aliasy, równie przydatne. Wyjaśnię bardzo pobieżnie, bo prawdopodobnie większość będzie oczywista dla większości użytkowników konsoli.

alias df        "df -h"
alias du        "/bin/du -h --max-depth=0"
alias duv       "/bin/du -h --max-depth=1"
alias duvv      "/bin/du -h"
alias for       "foreach"
alias ls        "ls --color -FbxhC"
alias la        "ls -a"
alias ll        "ls -l"
alias lll       "ls -la"
alias mntc0     "sudo mount /dev/hdc /mnt/cd0 -o uid=bartek"
alias mntc1     "sudo mount /dev/hdd /mnt/cd1 -o uid=bartek"
alias mntf      "sudo mount /dev/sda /mnt/flash -o uid=bartek"
alias mntf1     "sudo mount /dev/sda1 /mnt/flash -o uid=bartek"
alias umntc0    "sudo umount /mnt/cd0"
alias umntc1    "sudo umount /mnt/cd1"
alias umntf     "sudo umount /mnt/flash"

Alias df, dość oczywisty; z opcją, która każe wyświetlać wielkości w potęgach kilobajta. Aliasy du, duv i duvv to du z analogiczną opcją do df i w różnych poziomach "wylewności" (ang. verbose :)). W tym przypadku wywołuję du pełną ścieżką, gdyż samo du jest rozpoznawane jako alias. for jest aliasem dla foreach, który jest odpowiednikiem bashowego for w csh. ls, la, ll, lll to chyba dość typowe aliasy dla różnych wariacji na temat ls. Na koniec aliasy do montowania płyt cd i pamięci flash. Ot tak, żeby sobie oszczędzić czasu, bo trochę pisania jest. Podobnie z aliasami do odmonowywania powyższych.

W prawdzie jest jeszcze wiele rzeczy ułatwiających pracę z konsolą, takich jak nauczenie się języka powłoki, seda, awka, perla i całej reszty na fest; aczkolwiek myślę, że TO już daje możliwość uzyskania już dosyć silnego narzędzia. Zwłaszcza że wybrane przeze mnie opcje to nie wszystko co proponują zaprezentowane narzędzia (odsyłam oczywiście do mana).

Podstawy używania GNU Debugera.

2 komentarze

GDB jest jednym z ważniejszych narzędzi programisty w świecie *nixów. Zwłaszcza jeśli doliczy się jego frontendy. Tak czy inaczej, choć mogłoby się wydawać inaczej (ze względu na to, że jest w 100% CLI), jest bardzo potężnym i dość wygodnym narzędziem. Wystarczy poznać kilka podstawowych poleceń, żeby skutecznie odpluskwiać programy. Niestety nie znalazłem w polskim internecie, żadnych tutoriali o GDB, toteż postanowiłem się podzielić listą najczęściej używanych przeze mnie poleceń.

Na początek parę uwag technicznych. GDB, jak wspomniałem, uruchamiamy pod konsolą. Zwyle podajemy w linii polceń nazwę pliku z programem, który chcemy debugować (jeśli tego nie zrobimy, należy wydać polecenie "file <nazwa programu>"). Aby GDB miał dostęp do symbloli takich jak nazwy zmiennych, funkcji, itp, program musi być odpowiednio skompilowany (np. w przypadku gcc i nasma trzeba użyć przełącznika "-g"). Jeśli zamiast polecenia wpisze się pustą linię ("\n"), zostanie wykonanie poprzedniej operacji. Wpisanie w linii poleceń samych białych znaków nie spowoduje żadnego działania.

Gdy mamy załadowany program, z reguły robię jedną z dwóch rzeczy. Pierwszy przypadek to wystąpienie błędu takiego jak sygnały SIGSEGV i SIGABRT. Jest to szybka sprawa. Zaczynamy od razu od wpisania polecenia "run <linia poleceń>". Jeśli program jest interaktywny, działamy tak, żeby wywołać błąd. W momencie jego wystąpienia, GDB o tym poinformuje. Wówczas można użyć kilka razy polecenia "up", które poda miejsce, w którym została wywołana obecna funkcja. Zwykle pierwszych parę wywołań tego polecenia poda parę miejsc poza twoim programem (np. glibc). Przykładowo może wyglądać to tak:

bash-3.1$ gdb a.out
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-slackware-linux"...
(gdb) run
Starting program: /tmp/a.out 
*** glibc detected *** /tmp/a.out: free(): invalid pointer: 0x0804a009 ***
======= Backtrace: =========
/lib/libc.so.6[0xb7de98c4]
/lib/libc.so.6(cfree+0x90)[0xb7ded370]
/tmp/a.out[0x80483b2]
/lib/libc.so.6(__libc_start_main+0xe0)[0xb7d94390]
/tmp/a.out[0x8048321]
======= Memory map: ========
08048000-08049000 r-xp 00000000 03:06 575488     /tmp/a.out
08049000-0804a000 rw-p 00000000 03:06 575488     /tmp/a.out
0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]
b7c00000-b7c21000 rw-p b7c00000 00:00 0 
b7c21000-b7d00000 ---p b7c21000 00:00 0 
b7d72000-b7d7c000 r-xp 00000000 03:06 187042     /usr/lib/libgcc_s.so.1
b7d7c000-b7d7d000 rw-p 00009000 03:06 187042     /usr/lib/libgcc_s.so.1
b7d7d000-b7d7e000 rw-p b7d7d000 00:00 0 
b7d7e000-b7ec4000 r-xp 00000000 03:06 601542     /lib/libc-2.7.so
b7ec4000-b7ec5000 r--p 00146000 03:06 601542     /lib/libc-2.7.so
b7ec5000-b7ec7000 rw-p 00147000 03:06 601542     /lib/libc-2.7.so
b7ec7000-b7ecb000 rw-p b7ec7000 00:00 0 
b7ee9000-b7f05000 r-xp 00000000 03:06 601584     /lib/ld-2.7.so
b7f05000-b7f07000 rw-p 0001b000 03:06 601584     /lib/ld-2.7.so
bf8de000-bf8f3000 rw-p bffeb000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]

Program received signal SIGABRT, Aborted.
0xb7da8c66 in raise () from /lib/libc.so.6
(gdb) up
#1  0xb7daa571 in abort () from /lib/libc.so.6
(gdb) 
#2  0xb7de196b in __libc_message () from /lib/libc.so.6
(gdb) 
#3  0xb7de98c4 in _int_free () from /lib/libc.so.6
(gdb) 
#4  0xb7ded370 in free () from /lib/libc.so.6
(gdb) 
#5  0x080483b2 in main () at x.c:5
5               free (x+1);
(gdb) 

Drugi, właściwy przypadek jest taki, że coś nie działa tak jak powinno. Wówczas trzeba już znać kilka poleceń i GDB może pokazać więcej mocy. Podstawą w takim wypadku jest ustawienie breakpointa w miejscu w którym zaczniemy analizować program. Używamy do tego polecenia "break <gdzie przerwać>" gdzie parametrem może być nazwa funkcji (np. main) lub numer linijki. W przypadku programów wieloplikowych, numer linii można podać w postaci plik_zrodlowy:numer. Jeśli nie ma nazwy pliku, przyjmowany jest plik z którego pochodzą obecnie analizowane instrukcje (przed uruchomieniem przyjmowany jest plik z punktem startowym - w przypadku c/c++ plik z funkcją main). Jest również możliwość podania adresu.

Gdy jesteśmy w odpowiednim miejscu, czas na przemieszczanie się w programie. Służą do tego, między innymi, polecenia:

  • continue -- program jest kontynuowany. Zatrzyma się w przypadku zakończenia programu bądź natrafienia na breakpoint. Należy zaznaczyć, że linijka wypisana po natrafieniu na breakpoint nie zostaje już wykonana.
  • next -- zostaje wykonana kolejna linijka (ta ostatnio wypisana) po czym wypisywana jest kolejna i program zostaje zatrzymany.
  • step -- działa podobnie do next, z tym, że jeśli wywoływana jest w linii funkcja, której kod jest dostępny (tj. został skompilowany z odpowiednią flagą), gdb przejdzie do tej funkcji i będzie można ją przeanalizować.

Polecenia stepi i nexti działają analogicznie z tym, że wykonują tylko jedną instrukcję procesora.

Czasami uciążliwe jest to, że gdb wypisuje tylko jedną linijkę. Jeśli zachodzi potrzeba zobaczyć ją w szerszym konekście (nie mówiąc o przypadku, gdy w linii jest znak nowej linii) można użyć polecenia "list". Wówczas zostanie wypisana linia która zostanie wykonana jako następna, a także kilka poprzednich i kilka następnych. Jeśli tych kilka linijek to za mało, wpisać jeszcze raz, wówczas wypisanych zostanie jeszcze kilka następnych linii. Do polecenia list można dodać jeszcze numer linii (w takiej formie jak w break, może być również nazwa funkcji, itp). Wówczas zamiast obecnej linii, jako środkową będzie wzięta ta podana. W tym przypadku ponowne wpisanie polecenia zrobi to samo, a wciśnięcie entera wypisze kilka następnych".

Oczywiście można również podglądać wartości zmiennych. Służy do tego funkcja "print <wyrazenie>", gdzie wyrażenie może być praktycznie wszystkim. Może to być nazwa zmiennej, może to być wynik działania (na przykład dereferencji); może być to również rejestr procesora (wówczas należy przedzić go dolarem, np. "$eax"). Jest również możliwość wypisywania takiej informacji za każdym razem, gdy program zostaje zatrzymany. Wówczas używamy funkcji display. Tak wypisywane wartości są ponumerowane. Aby gdb przestał wypisywać tę wartość należy użyć funkcji "undisplay <numer>". Jeśli numer zostanie pominięty, usunięte zostaną wszystkie. W przypadku rejestrów jest również dodatkowa możliwość, funkcja "info registers", w skrócie "i r", która wypisuje stan wszystkich dostępnych rejestrów. Wygląda to mniej więcej tak:

(gdb) i r
eax            0xa      10
ecx            0x804a048        134520904
edx            0x804a020        134520864
ebx            0xb7fb8ff4       -1208250380
esp            0xbfce0d20       0xbfce0d20
ebp            0xbfce0d48       0xbfce0d48
esi            0xb7ff8ce0       -1207989024
edi            0x0      0
eip            0x804858e        0x804858e 
eflags         0x200346 [ PF ZF TF IF ID ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51

Jest to trochę więcej niż w przypadku print, więc można dodać jeszcze nazwę rejestru. Wówczas wypisany zostanie tylko ten rejestr. Na przykład "i r eflags"

Czasami wypisywanie pojedynczych zmiennych to zdecydowanie za mało. Wówczas można użyć polecenia examine do wypisania zawartości pamięci z danego adresu. Ma ona postać "x/[ile][podstawa][typ] wskaźnik". Szczęgóły w "help x". Na przykład, aby wypisać 12 słów 16 bitowych, w systemie szesnastkowym, spod adresu zapisanego w rejestrze ebp:

(gdb) x/12xh $ebp
0xbfb76bd8:     0x6c48  0xbfb7  0xe390  0xb7e1  0xfce0  0xb7f8  0x8d00  0x0804
0xbfb76be8:     0x6c48  0xbfb7  0xe390  0xb7e1

To już wszystko. Tych poleceń używam najczęściej i one wystarczają do całkiem sprawnego debugowania, choć oczywiście jest to zaledwie mała cząstka możliwości tego programu, wystarczy poczytać pomoc (polecenie "help") do czego zachęcam.

Czasami (może nawet trochę częściej) jeśli ściąga się filmy i napisy osobno występuje problem synchronizacją. Strasznie upierdliwa sprawa. Oczywiście zwykle jest to proste przesunięcie, w całym filmie, lub na przykład po każdej przerwie na reklamy, więc wystarczy trzymać paluchy na z i x (oczywiście, o ile używa się mplayera). Jest to oczywiście półśrodek, zwłaszcza jeśli owe filmy archiwizujemy i/lub dzielimy się nimi z innymi. Dlatego też napisałem prosty plugin dla vima, który pozwala bardzo łatwo i przyjemnie (najlepiej w połączeniu z mplayerem, w którym można łatwo kontrolować numer odtwarzanej w danym momencie klatki) poradzić sobie z problemem napisów pojawiających się za wcześnie lub za późno.

" Submaker -- video subtitle editor ver 20090611 - early one
" (c) by Bartosz Pastudzki 2009
" I wrote this file. As long as you retain this notice you can do whatever you
" want with this stuff. If we meet some day, and you think this stuff is worth
" it, you can buy me a beer in return.
 
" Split subtitle line into list of content : [start,end,text]
function SplitLine (line)
	let cline = getline (a:line)
	let start = match (cline, "{")
	if (start == -1)
		throw "start1"
	endif
	let end = match (cline, "}", start)
	if (end == -1)
		throw "end1"
	endif
	let subStart =  str2nr (cline[start+1 : end-1])
	if (start == -1)
		throw "start2"
	endif
	let start = match (cline, "{", end)
	let end = match (cline, "}", start)
	if (end == -1)
		throw "end2"
	endif
	let subEnd = str2nr (cline[start+1 : end-1])
	let content = match (cline, '\S', end+1) 
	return [subStart, subEnd, cline[content :] ]
endfunction
 
" Function opposite to SplitLine -- create valid subtitle line from content list
function JoinContent (content)
	return "{". a:content[0] . "}{" . a:content[1] . "}" . a:content[2]
endfunction
 
" Function to find out if subtitle file is valid
function Validate () 
	for lineNum in range (1,line ("$"))
		try
			call SplitLine (lineNum)
		catch /.+/
			return lineNum
		endtry
	endfor
	return -1
endfunction
 
" Low level version of Delay. It takes numbers of lines too. It's not intended
" to be called directly by user.
function DelayLL (delay, start, end)
	for line in range (a:start,a:end)
		let content = SplitLine (line)
		let content[0] += a:delay
		let content[1] += a:delay
		let nline = JoinContent (content)
		call setline (line, nline)
	endfor
endfunction
 
" Delay selected part of text
function DelayS (delay)
	call DelayLL (a:delay, a:firstline, a:lastline)
endfunction
 
" Standard delay, from current line to the end
function Delay (delay)
	call DelayLL (a:delay, line ("."), line ("$"))
endfunction
 
function GoToFrame (frame)
	let linenum = 0
	while 1
		let linenum += 1
		let last = SplitLine (linenum)
		if (last[1] >= a:frame)
			break 
		elseif (linenum == line ("$"))
			break
		endif
	endwhile
	call setpos (".", [0,linenum,1])
endfunction
 

Aby móc używać go w dowolnym momencie, należy zapisać go na dysku, w odzielnym pliku i do pliku .vimrc dodać linijkę "source ". Funkcjami, które służą do używania z zewnątrz są Delay, DelayS i GoToFrame.

Funkcja Delay opóźnia wszystkie napisy od linii w której znajduje się kursor do końca. Na przykład wywołanie ":call Delay (-5)" przesunie je o 5 klatek w tył.

Funkcja DelayS działa tak samo jak Delay, z tą różnicą przesuwa tylko te zaznaczone.

Funkcja GoToFrame przesuwa kursor do linijki, w której znajduje się napis, który się wyświetli się w klatce podanej w parametrze bądź następnego, jeśli w tej klatce nie ma żadnego napisu.

Należy zaznaczyć, że program działa tylko dla napisów w formacie "{start}{koniec} napis" i nie zadziała poprawnie jeśli liczba klatek przekroczy zakres 32-bitowej liczby ze znakiem (231).

Mam nadzieję, że komuś się przyda, będę wdzięczny za wszelkie uwagi i sugestie, ewentualnie łatki.

Bardzo skrótowa prezentacja GNU R.

11 komentarzy

Już od dłuższego czasu używam LaTeXa i bardzo sobie go chwalę. W sumie, myślę, że chyba nikogo kto miał przyjemność z tego narzędzia korzystać, nie trzeba przekonywać o jego licznych zaletach. W tym semestrze jeszcze częściej go używam, ze względu na sprawozdania z laboratoriów z miernictwa. Nie dbam o to jak to robią inni, ale ja sobie cenię estetykę dokumentów (trzeba się naprawdę postarać, żeby LaTeX coś złożył brzydko) i bardzo wygodne składanie wzorów matematycznych, tudzież wcale niezły system referencji. Jest jednak luka w funkcjonalności (oczywiście nie uważam, że to źle, przeciwnie) LaTeXa jaką odczułem przy okazji pisania wspomnianych sprawozdań, nie daje dobrego sposobu na generowanie wykresów. W tym miejscu z pomocą przychodzi GNU R.

GNU R stanowi bardzo dobre uzupełnienie dla LaTeXa, głównie dlatego, że i ten opiera się o napisanie paru linijek kodu na podstawie którego można wygenerować żądany wykres w jednym z kilku dostępnych formatów (między innymi svg, png). Można też po prostu wyświetlić ten wykres na ekranie. Jak dla mnie to świetna sprawa.

Prosty wykres to kwestia paru linijek, na przykład:

png(file="test.png", width=400, height=400)
ib <- seq(50,300, by=50)
delta <- c(5.7, 5.3, 3.68, 3.24, 3.30, 1.93)
plot(ib, delta, xlab="Ib[mA]", ylab="Bład względny[%]")
abline(6.45, -0.015)

W sumie wszystko właściwie widać. Określamy output (plik.png). Tworzymy dwie listy (ib i delta) które wykorzystamy jako współrzędne dla naniesionych punktów. W pierwszym przypadku użyta została funkcja seq(x,y, by=z), która zwraca tablicę elementów od x do y co z. W przypadku delta użyłem funkcji c(e1, e2, e3, ..., en), która po prostu tworzy tablicę z danych argumentów. W następnej linijce jest funkcja plot, która rysuje wykres z naniesionymi punktami, których kolejne współrzędne x są wzięte z ib, a współrzędne y z delta. Dalej znajdują się jeszcze opcjonalne wartości xlab i ylab zawierające opisy osi. Pominięto też parametr, którym można ustawić, by punkty były połączone łamaną. Na sam koniec rysuję prostą przy pomocy funkcji abline, która jest nieco nieintuicyjna ze względu na to, że przyjmuje wartość y dla x = 0 i współczynnik kierunkowy, niezależne od skali i przedziałów jakie będą przyjęte dla poszczególnych osi, ale w sumie to dobrze, że tak jest.

W wyniku przetworzenia takiego kodu otrzymamy coś takiego:
Free Image Hosting at www.ImageShack.us
Jest to oczywiście kwestia gustu, ale jak dla mnie jest to rozwiązanie szybsze, wygodniejsze i łatwiejsze w modyfikacji od konkurencji, dajmy na to Microsoft Excel.

Oczywiście jest to bardzo mała cząstka możliwości tego narzędzia (szczerze mówiąc sam ledwo je poznałem ;)), można wygenerować całą masę fajnych wykresów (tu odsyłam do polecenia demo(graphics) w interpreterze GNU R, który pokaże kilka wykresów – takich już pro, nie to co ja wam zaserwowałem ;p – wraz z kodami źródłowymi). To by było na tyle, ale jednak tekst ten powstał jedynie po to by zasygnalizować, że taka zabawka istnieje i nie jest zbyt popularna, a przecież bywa dość przydatna.

Generator menu dla fluxboksa.

2 komentarze

Jakiś czas temu zaprezentowałem mój pierwszy skrypt PHP, przygoda z tym językiem szybko się zakończyła. Przyszedł czas na perla – aż wstyd się przyznać, że dopiero teraz. Tak czy inaczej, po dość oględnym przestudiowaniu języka przyszedł czas na chrzest bojowy - napisanie skryptu, który generowałby menu na podstawie /usr/share/applications/. Być może jest już coś takiego, ale jak wszystkim dobrze wiadomo, jestem bardzo leniwy. Zadanie może nie wydające się być trudnym (choć pisanie w tego C to niezbyt kusząca perspektywa), aczkolwiek dobrze zweryfikowało to co zrozumiałem z kursu.

Zacznijmy od tego, jak ten skrypt działa. Mianowicie, parsuje on plik z szablonem (~/.fluxbox/menu.templ) i pliki *.desktop z /usr/share/applications/ i na podstawie informacji w nich zawartych buduje menu. Skrypt nie jest jeszcze doskonały i będzie wymagał dość radykalnego przerobienia, tak by elementy mogły być sortowane alfabetycznie i obsługiwały lokalizacje. Niemniej jednak działa i dość dobrze i szybko (w moim przypadku 0,03s) wypełnia swoje zadanie.

Pliki szablonowe mają bardzo prostą budowę – są to zwyczajne pliki menu fluxboksa, wzbogacone o wtrącenia w nawiasach ostrych (muszą być w oddzielnych linijkach), informujących program, jak interpretować /usr/share/applications/. Mój plik szablonu wygląda następująco i wyczerpuje opcje, które można póki co wtrącić:

<setterm urxvt -font -*-fixed-medium-r-*-*-20-*-*-*-*-*-*-2 -fg white -bg black>
<show-groups Network,Utility,AudioVideo,Game,Application,Office,Graphics,Science,System>
[begin] (Fluxbox)
[encoding] {UTF-8}
  [exec] (uruchom) {fbrun}
  <addterm terminal>
  [exec] (WWW) {seamonkey}
  [exec] (e-mail) {seamonkey --mail}
  [exec] (vim) {gvim}
  <insert-here>
  [exec] (uaktualnij menu) {/home/bartek/fluxmenugen.pl}
  [restart]
  [exit]

jak widać, nie jest tego dużo:

  • Na samym początku polecenie setterm, ustawiające polecenie terminala, dla opcji addterm i do otwierania pozycji terminalowych (ewentualność jeszcze nie przetestowana, ale nie widzę powodu, dla którego miałaby nie działać ;p).
  • Potem rzecz najważniejsza - show-groups – wybiera, które grupy pokazać – za dużo tych grup się definiuje w plikach *.desktop, żeby je wszystkie wrzucić do menu. Póki co nie może być odstępu między nazwą, a przecinkiem.
  • Wspomniany już addterm, który wstawia polecenie terminala o opisie wpisanym dalej (w tym przypadku, "terminal").
  • insert-here w którego miejscu pojawią wygenerowane pozycje. Należy zwrócić uwagę na fakt, że można umieścić je w kilku miejscach, dla różnych konfiguracji show-groups. Należy również zaznaczyć, że grupy pojawią się w takiej samej kolejności jak podano w tej opcji.

Na sam koniec natomiast gotowy skrypt, który udostępniam do dowlonego użytku.

#! /usr/bin/perl -w
 
$sdir = "/usr/share/applications";
$sext = ".desktop";
$favterm = "urxvt";
 
$destdir = $ENV{'HOME'}."/.fluxbox/";
open (TEMPLATE, $destdir."menu.templ") || die "Failed to open template file.";
if(open (DESTINATION, $destdir."menu"))
{
  open (BACKUP, ">".$destdir."menu~");
  while ( <DESTINATION> )
  {
    print BACKUP;
  }
  close (BACKUP);
}
close ( DESTINATION );
 
open (DESTINATION, ">".$destdir."menu");
 
opendir ( SHORTCUTS, $sdir ) || die ("failed to open $sdir.");
@shortcuts = grep { m/$sext$/ } readdir ( SHORTCUTS );
closedir ( SHORTCUTS );
 
%groups = ();
$ungrupped = "";
 
foreach $shortcut ( @shortcuts )
{
  open ( SHORTCUT, $sdir."/".$shortcut);
  while ( <SHORTCUT> )
  {
    if ( m/^Name=(.+)(\s*)$/ )
    {
      $name = $1;
    }
    elsif ( m/^Exec=(.+)(\s*)$/ )
    {
      $cmd = $1;
    }
    elsif ( m/^Terminal=(.+)(\s*)$/ )
    {
      $term = $1;
    }
    elsif ( m/^Categories=(.+)(\s*)$/ )
    {
      @cats = split ( /;/, $1 );
    }
  }
  if ( !defined ( $name ) || !defined ( $cmd ) )
  {
    print "Failed to find essentional values for $shortcut\n";
  }
  else
  {
    if ( defined ( $term ) && $term eq "true" )
    {
      $cmd = $favterm." -e \"".$cmd."\"";
    }
    $stext = "[exec] ($name) {$cmd}\n";
 
    if ( !defined ( @cats ) )
    {
      $ungrupped .= $stext;
    }
    else
    {
      foreach $cat ( @cats )
      {
        $groups{$cat} .= $stext;
      }
    }              
  }
}
 
while ( <TEMPLATE> )
{
  if ( @tags = m/<(.+)>/g )
  {
    foreach $tag (@tags)
    {
      if ( $tag eq "insert-here" )
      {
        if ( defined ( @tagWhitelist ) )
        {
          foreach $group ( @tagWhitelist )
          {
            print DESTINATION "[submenu] ($group)\n";
            print DESTINATION $groups{$group};
            print DESTINATION "[end]\n"
          }
        }
        else
        {
          foreach $group ( keys %groups )
          {
            print DESTINATION "[submenu] ($group)\n";
            print DESTINATION $groups{$group};
            print DESTINATION "[end]\n"
          }
        }
        print DESTINATION $ungrupped;
      }
      elsif ( $tag =~ /^setterm (.+)/ )
      {
        $favterm = $1;
      }
      elsif ( $tag =~ /^addterm (.+)/ )
      {
        print DESTINATION "[exec] ($1) {$favterm}\n";
      }
      elsif ( $tag =~ /^show-groups (.+)$/ )
      {
        if ( defined ( @tagWhitelist ) )
        {
          push ( @tagWhitelist, split ( /,/, $1 ) );
        }
        else
        {
          @tagWhitelist = split ( /,/, $1 );
        }
      }
      elsif ( $tag =~ /^show-all/ )
      {
        undef ( @tagWhitelist );
      }
    }
  }
  else
  {
      print DESTINATION;
  }
}

i efekt:
Free Image Hosting at www.ImageShack.us

Desktop bez gryzonia? To możliwe!

23 komentarze

Zapewne większość miłośników edytorów tekstów takich jak Vim, czy emacs, a także wyznawcy wyższości CLI nad GUI, przyzna, że klawiatura jest znacznie szybsza, a jeśli się człowiek przyzwyczai, wygodniejsza od myszki. Ciężko jednak wyeliminować z środowiska graficznego użycie myszy. Nic bardziej mylnego, mając odpowiednie narzędzia można bez problemu używać Xów bez myszki, ani jej emulacji. Pomijając kilka dziedzin, w których raczej myszkę ciężko zastąpić(u mnie chyba tylko edytor grafiki, GIMP). W tym artykule przedstawię zarządcę okien sterowanego klawiaturą - awesome.

Już bardzo dawno mysz zadomowiła się w systemach biurkowych. Nic dziwnego, przesuwanie okien "chwytając" je kursorem myszy i wciskanie nim przycisków jest bardzo intuicyjne. Być może gdyby nie wymyślono myszy, komputery nie byłby tak powszechne. Istnieje jednak pewna grupa ludzi myśli w trochę innych kategoriach. Owocem takiego myślenia jest pomysł na zarządzanie oknami bez użycia myszy.

Pierwszą, rzeczą jaka przychodzi na myśl(przynajmniej mi przyszła;)), słysząc o zarządcy okien sterowanym klawiaturą, to "Jak to, do cholery, możliwe?". Rozwiązanie jest bardzo proste. Wystarczy, że rozmieszczeniem i zmianą rozmiarów okien zajmie się program, pozostałe rzeczy można zrobić klawiaturą, nawet w "klasycznych" środowiskach. W praktykce wygląda to mniej więcej tak:
Free Image Hosting at www.ImageShack.us

Wbrew pozorom istnieje dość sporo takich programów: ratpoison, Ion, wmii, dwm, awesome. W tym tekście skupię się na tym ostatnim. Myślę, że każdy sobie poradzi z instalacją tego programu(jeśli nie ma go w repo twojej dystrybucji :poszukaj na freshmeat), więc przejdę od razu do rzeczy.

Podobnie jak w przypadku większości programów open source, kluczem do sukcesu jest dobra konfiguracja, którą przeprowadzamy poprzez edycję pliku ~/.awesomerc . Jego struktura jest dość prosta i można bardzo łatwo ją zrozumieć, próbując przy niej majstrować i posiłkować się manem. Jednakże, aby ułatwić Ci sprawę, przedstawię mój plik konfiguracyjny awesome i pokrótce wyjaśnię, o co chodzi. Nie będę się wdawał w zbędne szczegóły, bo o co chodzi, każdy widzi. Chyba jedyny szczegół, jaki wypada nadmienić to występujący klawisz Mod4. Jego definicja jest kwestią konfiguracji X11, w najpopularniejszych u nas klawiaturach Microsoft będzie to logo Windows. Swoją drogą, bardzo fajnie, że znajduje on wreszcie jakieś logiczne zastosowanie. :)

Mój plik konfiguracyjny składa się z trzech sekcji(jest ich więcej, jednakże nie odczułem potrzeby zgłębiania ich zastosowania :)). Pierwszą z nich jest sekcja screen:

screen 0
{
    styles
    {
        normal
        {
            font = "sans 8"
            fg = "#dddddd"
            bg = "#444444"
            border = "#555555"
        }
        focus
        {
            fg = "#000000"
            bg = "#535d6c"
            border = "#535d6c"
        }
        urgent
        {
            fg = "#111111"
            bg = "#ff4500"
        }
    }
    tags
    {
        tag one { }
        tag two { }
        tag three { }
        tag four { }
        tag five { }
        tag six { }
        tag seven { }
        tag eight { }
        tag nine { }
    }
    layouts
    {
#        layout tile { image = "/usr/share/awesome/icons/layouts/tilew.png" }
#        layout tileleft { image = "/usr/share/awesome/icons/layouts/tileleftw.png" }
        layout tilebottom { image = "/usr/share/awesome/icons/layouts/tilebottomw.png" }
#        layout tiletop { image = "/usr/share/awesome/icons/layouts/tiletopw.png" }
#        layout max { image = "/usr/share/awesome/icons/layouts/maxw.png" }
#        layout spiral { image = "/usr/share/awesome/icons/layouts/spiralw.png" }
#        layout dwindle { image = "/usr/share/awesome/icons/layouts/dwindlew.png" }
#        layout floating { image = "/usr/share/awesome/icons/layouts/floatingw.png" }
    }
    statusbar mystatusbar
    {
        position = "top"

        taglist mytaglist
        {
            mouse
            {
                button = "1"
                command = "tag_view"
            }
            mouse
            {
                button = "1"
                modkey = {"Mod4"}
                command = "client_tag"
            }
            mouse
            {
                button = "3"
                command = "tag_toggleview"
            }
            mouse
            {
                button = "3"
                modkey = {"Mod4"}
                command = "client_toggletag"
            }
            mouse
            {
                button = "4"
                command = "tag_viewnext"
            }
            mouse
            {
                button = "5"
                command = "tag_viewprev"
            }
        }
        layoutinfo mylayoutinfo
        {
            mouse
            {
                button = "1"
                command = "tag_setlayout"
                arg = "+1"
            }
            mouse
            {
                button = "4"
                command = "tag_setlayout"
                arg = "+1"
            }
            mouse
            {
                button = "3"
                command = "tag_setlayout"
                arg = "-1"
            }
            mouse
            {
                button = "5"
                command = "tag_setlayout"
                arg = "-1"
            }
        }
        tasklist mytasklist{}
        iconbox logo
        {
            image = "/usr/share/awesome/icons/awesome16.png"
            mouse
            {
                button = "1"
                command = "spawn"
                arg = "exec xterm -e man awesome"
            }
        }
    }

Na samym początku mamy podsekcję styles, zostawiłem wartości domyślne. Dalej mamy podsekcję "tags". Zawiera ona listę tagów, czyli po prostu pulpitów.

Dalej, w kolejności jest podsekcja layouts. Opisuje ona sposoby rozmieszczania okien. Jak można zauważyć, owe sposoby definiuje się poprzez utworzenie odpowiedniego obrazka. Można również je przełączać(standardowo Mod4 + spacja), jednakże zakomentowałem wszystkie oprócz jednego, moim zdaniem najwygodniejszego układu, w którym główne okno(względnie okna) znajduje się u góry, a pozostałe, mniejsze są rozmieszczane poniżej. Szczerze powiedziawszy jest to nawet lepsze od tacki systemowej, bo nie zajmuje wiele miejsca, a za to przekazuje więcej informacji.

Dalej mamy sekcję "statusbar", dotyczącą cosia, w innych środowiskach zwanego panelem. Pozostawiłem wartości domyślne, bo w zasadzie nic poza listą tagów, listą layoutów i listą okien, nie jest mi na tyle potrzebne, żeby chciało mi się wystarczająco zagłębić w dokumentacji. :) Nie mam więc zegarka, jest to trochę problematyczne, ale rozwiązałem to uruchamiając na starcie xclocka, tak żeby pokazywał godzinę i datę w prawym-dolnym rogu. Dla mniej zaznajomionych w użyciu tego programu podaję wiersz polecenia dla cyfrowego zegara w formacie "dzień tygodnia, dzień.miesiąc.rok(2 cyfry) godzina:minuty", dla rozdzielczości 1280x1024:

xclock -geometry 170x30+1110+994 -d -twentyfour -strftime "%a,%d.%m.%y %H:%M"

Dalej mamy sekcję rules. Dotyczy ona wyjątkowych właściwości dla niektórych programów. W moim przypadku ogranicza się do wskazania, które okna mają "pływać", czyli nie podlegać layoutowi:

rules
{
    rule { name = "Gimp" float = true }
    rule { name = "MPlayer" float = true }
    rule { name = "Acroread" float = true }
    rule { name = "pinentry" float = true }
    rule { name = "xclock" float = true }
}

Ostatnią i chyba najważniejszą sekcją, jest sekcja keys, definiująca skróty klawiszowe:

keys
{
    key
    {
        modkey = {"Mod4"}
        key = "F1"
        command = "spawn"
        arg = "exec xfrun4"
   } 
    key
    {
        modkey = {"Mod4"}
        key = "F2"
        command = "spawn"
        arg = "ls .menu-items | awesome-menu -e \"exec ~/.menu-items/\""
    }
    key
    {
        modkey = {"Mod4"}
        key = "F3"
        command = "spawn"
        arg = "mpc toggle"
    }
    key
    {
       modkey = {"Mod4"}
       key = "F4"
       command = "spawn"
       arg = "exec xterm -e \"mpc&&sleep 2\""
    }
    key
    {
        modkey = {"Mod4"}
        key = "F5"
        command = "spawn"
        arg = "exec ario"
    }
    key
    {
        modkey = {"Mod4"}
        key = "Return"
        command = "spawn"
        arg = "exec ~/.menu-items/Terminal"
    }
    key
    {
        modkey = {"Mod4"}
        key = "space"
        command = "tag_setlayout"
        arg = "+1"
    }
    key
    {
        modkey = {"Mod4", "Shift"}
        key = "space"
        command = "tag_setlayout"
        arg = "-1"
    }
    key
    {
        modkey = {"Mod4"}
        key = "b"
        command = "statusbar_toggle"
    }
    key
    {
        modkey = {"Mod4"}
        key = "Right"
        command = "client_focusnext"
    }
    key
    {
        modkey = {"Mod4"}
        key = "Left"
        command = "client_focusprev"
    }
    key
    {
        modkey = {"Mod4", "Shift"}
        key = "Right"
        command = "client_swapnext"
    }
    key
    {
        modkey = {"Mod4", "Shift"}
        key = "Left"
        command = "client_swapprev"
    }
    key
    {
        modkey = {"Mod4"}
        key = "p"
        command = "tag_setmwfact"
        arg = "-0.05"
    }
    key
    {
        modkey = {"Mod4"}
        key = "o"
        command = "tag_setmwfact"
        arg = "+0.05"
    }
    key
    {
        modkey = {"Mod4", "Control"}
        key = "p"
        command = "tag_setncol"
        arg = "+1"
    }
    key
    {
        modkey = {"Mod4", "Control"}
        key = "o"
        command = "tag_setncol"
        arg = "-1"
    }
    key
    {
        modkey = {"Mod4"}
        key = "z"
        command = "tag_viewprev"
    }
    key
    {
        modkey = {"Mod4"}
        key = "x"
        command = "tag_viewnext"
    }
    key
    {
        modkey = {"Mod4"}
        key = "m"
        command = "client_togglemax"
    }
    key
    {
        modkey = {"Mod4", "Control"}
        key = "Return"
        command = "client_zoom"
    }
    key
    {
        modkey = {"Mod4", "Control"}
        key = "space"
        command = "client_togglefloating"
    }
    key
    {
        modkey = {"Mod4", "Control"}
        key = "c"
        command = "client_kill"
    }
    key
    {
        modkey = {"Mod4", "Control"}
        key = "q"
        command = "quit"
    }
    key
    {
        modkey = {"Mod4", "Control"}
        key = "r"
        command = "restart"
    }
    key
    {
       modkey = {"Mod4"}
       key = "0"
       command = "tag_view"
    }
    keylist
    {
        modkey = {"Mod4"}
        command = "tag_view"
        keylist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
        arglist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
    }
    keylist
    {
        modkey = {"Mod4", "Shift"}
        command = "client_tag"
        keylist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
        arglist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
    }
    keylist
    {
        modkey = {"Mod4", "Control"}
        command = "client_toggletag"
        keylist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
        arglist = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
    }
}

Myślę, że nie trudno zrozumieć zapis. Jedynie komendy mogą być nieco nie jasne, dlatego wyjaśnię kolejne skróty:

  1. Mod4+F1 - uruchamia xfrun4, czyli pochodzące z xfce4 "uruchom...". (byłbym wdzięczy jeśli ktoś by wskazał narzędzie tego typu spoza konkretnego środowiska).
  2. Mod4+F2 - uruchamia menu awesome'a. Jak widać listę komend ustala się w wierszu polecenia. W tym przypadku owa lista składa się z dowiązań/skryptów utworzonych w katalogu ~/.menu-items .
  3. Mod4+F3 - włącza/wyłącza muzykę(dla użytkowników MPD).
  4. Mod4+F4 - wyświetla obecnie odtwarzany utwór(również dla MPD)
  5. Mod4+F5 - uruchamia ario - mojego ulubionego klienta MPD.
  6. Mod4+Enter - uruchamia terminal. Tu xterm z czarnym tłem i białą czcionką kurierową
  7. Mod4+Space - następny layout. Zostawiłem tak na wszelki wypadek.
  8. Mod4+Shift+Space - poprzedni layout
  9. Mod4+b - włacza/wyłącza panel.
  10. Mod4+Strzałka_w_lewo/Strzałka_w_prawo - skupia się na poprzednim/następnym oknie
  11. Mod4+Shift+Strzałka_w_lewo/Strzałka_w_prawo - przenosi obecne okno o pozycję w lewo/prawo na liście otwartych okien, co skutkuje zmianą głównego okna.
  12. Mod4+o/p - zwiększa/zmniejsza przestrzeń zajmowaną przez główne okno
  13. Mod4+Control+o/p - zwiększa/zmniejsza liczbę kolumn w których układane są okna.
  14. Mod4+z/x - przełącza na poprzedniego/następnego taga
  15. Mod4+m - maksymizuje okno(i odwraca ten proces).
  16. Mod4+Control+Enter - sprawia, że aktywne okno staje się głównym oknem
  17. Mod4+Control+Space - włącza/wyłącza "pływanie" aktywnego okna.
  18. Mod4+Control+c - zamyka okno.
  19. Mod4+Control+q - zamyka awesome.
  20. Mod4+Control+r - uruchamia ponownie awesome.
  21. Mod4+0 - sprawia, że pokazywane są okna ze wszystkich tagów
  22. Mod4+cyferki_1_-_9 - przełączają na kolejne tagi
  23. powyższe z shiftem - przenosi okno na konkretnego taga
  24. poprzednie z controlem - sprawia, że aktywne okno pojawi się również w konkretnym tagu(i odwraca ten proces).

To wszystko, taki stan rzeczy mnie w pełni satysfakcjonuje i sprawia, że niechętnie sięgam po gryzonia, w związku z czym programy też obsługuję klawiaturą, co z kolei sprawia, że pracuje się szybciej. W przyszłości być może będę drążył ten temat. :)

Nagrywanie systemów plików złożonych z dużej ilości katalogów przy użyciu growisofs jest nieco kłopotliwe, bo jest dużo pisania, głównie przez ustawianie graft pointów. GNOME baker natomiast nie oferuje mi zbyt wielkiego pola do popisu, jeśli chodzi o konfigurację (jestem ślepy, czy naprawdę nie można wybrać, czy użyć Jolieta czy Rock Ridge?). Dlatego też, powodowany wrodzonym lenistwem, postanowiłem coś z tym zrobić.

Mianowicie napisałem prosty skrypt, który za nas załatwi graft pointy, a nawet sprawdzi, czy należy użyć opcji -Z czy -M. Powodowany wspomnianym lenistwem zmiana opcji odbywa się poprzez edycję skryptu (w przedstawionej wersji instaluje tylko rock-ridge). Składnia natomiast jest prosta. W argumentach wpisujemy nazwy katalogów(można spokojnie używać gwiazdki). Natomiast parametry "-f" i "-d" odpowiednio informują program, czy dane dalej parametry oznaczają pliki, czy katalogi(domyślnie katalogi). Jeśli podamy nazwę katalogu wśród plików, zostanie nagrana jego zawartość. Po wprowadzeniu polecenia program wydrukuje linię poleceń i poprosi o zatwierdzenie. Skrypt wymaga growisofsa i cdrdao, jest napisany dla archa (więc może być konieczność zmiany /dev/sr0 na odpowiednią dla twojego systemu ścieżkę). Kto chce, niech bierze:

#! /bin/bash

if [ -n "$1" ]
then
  echo Burner, enter with names of wanted directories to burn on /dev/sr0 with rock-ridge, and with no joliet
else
  isempty=`cdrdao disk-info --device /dev/sr0 | grep "CD-R empty" | grep "no"`
  if [ "$isempty" == "" ]
  then
    echo -n "growisofs -Z=/dev/sr0 -R --graft-points " > .burnertmp
  else
    echo -n "growisofs -M=/dev/sr0 -R --graft-points " > .burnertmp
  fi
  isfile=0      
  for x in "$@"
  do
    case $x in
      "-f") isfile=1 ;;
      "-d") isfile=0 ;;
      *) if [ "$isfile" == 1 ]
           then
             echo -n "\"`echo $x`\" " >> .burnertmp
             else
             echo -n "\"`echo $x`\"=\"`echo $x`\" " >> .burnertmp
            fi ;;
    esac
  done

  cat .burnertmp
  echo
  echo "Is that ok? If so press ENTER, CTRL+C to cancel"
  read
  chmod +x .burnertmp
  ./.burnertmp
  rm .burnertmp
fi

Jigsaw download [jigdo]

9 komentarzy

Zdąrzyłem się zdecydować już na Debiana. Na stronie projektu natrafiłem na nową - całkiem ciekawą metodę ściągania obszernych dystrybucji - Debian z pewnością taką jest - 3 płytki DVD to jednak jest już coś ;). Chodzi o skrypt, który nazywa się Jigsaw download, w skrócie jigdo

Jak to działa? Bardzo prosto. Zamiast pliku ISO ściągamy plik o rozszerzeniu jigdo, zawierający nazwy plików wchodzących w skład dystrybucji, wraz z sumami kontrolnymi, ściąga je z podanych przez użytkownika serwera i robi z nich obraz pyły. Podono forma ta ma wyprzeć tradycyjne pliki ISO. Zasadniczo nic dziwnego, bo trzykrotne( CD, DVD i pojedyńcze paczki) duplikowanie danych to chyba nie zbyt ekonomiczna metoda.
strona projektu : http://atterer.net/jigdo/

Polak potrafi II : PLD Ac

24 komentarze

Ostatnio zdecydowałem się spróbować kolejnej polskiej dystrybucji Linuksa - PLD Linux Distribution, podobnie jak w przypadku KateOS uzyskuje miejsce w czołówce najlepszych według mnie systemów( Nota bene tylko jeden system ma tam stałą i nie zagrożoną przez nic lokatę ;)).

PLD jest pierwszą( tak przynajmniej mi wiadomo ;)) rozwijaną głównie przez Polaków, w związku z tym dawniej nazywała się Polish(ed) Linux Distribution. Przy okazji należy też do największych dystrybucji na świecie. System ten opiera się na paczkach RPM, a do zarządzania nimi używa świetnego programu poldek. Innym wielkim atutem PLD jest szybkość - bez problemu dorównuje Archowi i Gentoo. Cechuje się również rozdrobnieniem paczek na mniejsze w celu zaoszczędzenia miejsca na dysku. Za PLD opowiada się również fakt, iż znajdziemy w nim aż 691 polskich czcionek

Nie ma niestety róży bez kolców - PLD ma swoje wady. Najpoważniejszą z nich moim z zdaniem jest niedopracowanie niektórych paczek. Przykładowo paczka z MPD1 nie zawiera przykładowego pliku mpd.conf( co jeszcze nie jest takim błędem, bo można go napisać na podstawie manuala) oraz skryptu startowego, co jest już poważnym uniedogodnieniem. Innym przykładem może być gajim, który po prostu nie działa( w wyniku błędów biblioteki pysqlite). Innym powodem do niezadowolenia jest uboga dokumentacja, zwłaszcza jeśli przyrównamy ją do takich projektów jak Gentoo, FreeBSD, czy Debian. Moim zdaniem PLD mógłby rozszerzyć kolekcję dockappów ;)

Nie jestem pewien, czy PLD jeszcze długo zabawi na moim dysku. Myślę, że raczej jednak nie zainstaluję znów Gentoo ze względu na to, że nie będzie mi się chciało znów wszystkiego kompilować. Może dam nową szansę Debianowi, który pewnie ma pokaźną kolekcję dockappów, a poza tym nie miałem wielkich powodów, by z niego migrować.

Tak czy inaczej PLD zajmuje bardzo wysoką pozycję - nie jestem do końca pewien, czy drugą, czy trzecią( nie bije na pewno FreeBSD), gdyż nie jestem do końca pewien, jak go ustosunkować do Gentoo. lepszy od Slacka i na pewno znacznie lepszy od KateOSa i Archa. Potem jest DOS jako kochany zabytek. Następnie trzy dystrybucje których w życiu nie tknę : Red Hat, Mandriva, SuSE i na koniec systemy którym nic nie zagrozi zrzuceniem z zaszczytnej, ostatniej lokaty : Micro$oft Window$. Nie uwzględniłem tu OpenBSD, który raczej nie jest przeznaczony na desktop, Ubuntu, który raczej nie jest dystrybucją dla mnie, ze względu na fakt iż nie potrzebuję pomocy w doborze pakietów i konfiguracji Debiana. I Debiana, któremu muszę się dopiero przyjrzeć.

Na koniec natomiast link dla wszystkich, którzy muszą rozładować stres/lubią niszczyć/są piromanami2 do listy firm, które należy puścić z dymem : http://www.microsoft.com/poland/windowsserversystem/fakty/default.mspx



_____________________________
1 Music Player Daemon - program rezydentny służący do odtwarzania muzyki
2 Niepotrzebne skreślić

Polak potrafi - Parę słów o "Kaśce" cz1

13 komentarzy

Wiadomo było, że długo nie usiedzę na tym Gentoo ;) Postanowiłem wypróbować parę razy poleconą mi na jakilinux.org dystrybucję KateOS. Tak więc wypada napisać o tej dystrybucji.

Tak w jednym zdaniu, to musi być to naprawdę dobre distro, bo nawet problemy z netem, które uniemożliwiały mi ściągnięcie podstawowych paczek( instalowałem z miniiso) nie obrzydziły mi tego systemu ;). Tak bardziej dokładnie. Całkiem miły proces instalacji, raczej bez zgrzytów. Po reboocie powitał mnie całkiem ładnie ustawiony grub( mam na myśli graficzkę nań nałożoną), a potem ładne logo KATEOS przy bootowaniu, a potem ładny framebuffer z tym samym logo w tle. Nie jest to dla mnie żaden wielki plus, ale miło się pracowało ;) dopóki nie przeszedłem na X11, które udało mi się skonfigurować nadzwyczaj łatwo( no może oprócz faktu, że mam rozdzielczość 1024x768, a zdążyłem już przywyknąć do 1280x1024 wrrr... Jakie to wszystko wielgachne). Zasadniczo pierwsze sekundy po uruchomieniu WindowMakera( a czegóż by innego ;)) były dla mnie traumatyczne - w życiu nie widziałem tak przesłodzonego pulpitu - tfu tfu. Nie jest to jednak, żaden wielki problem, bo wystarczyło poświęcić parę minut na przestawienie tła na czarne i skombinowania jakichś ładnych kolorków. Następnym minuchem jest wyposażenie repo - brak opery, czy MPD, nawet, niech stracę, gajima jeszcze zdzierżę, ale tego, że jest windowmaker, a nie ma żadnych dockappów już nie rozumiem... Cóż ściągnie się. W zamian za to system jest dość szybki i mało kłopotliwy. No i wielki plus mało związany z developerami Kaśki to to, że wreszcie obejrzałem 11 odcinek Naruto Shippuudena( geez - od piątku nie miałem na dysku, żadnego Linuksa działającego dobrze :/). Zaraz chyba zapakuję się do wyrka i od jutra rana biorę się za dociąganie potrzebnych rzeczy. Jutro pewnie napiszę jeszcze trochę więcej o Kasi. Właściwie to może i nie bo dawno nie pisałem i trochę tematów mam, choćby porozwodzić się na temat Nietzschego ;). Pozdrawiam i z góry dziękuję za wszelkie wskazówki co do tej rozdzielczości. PS. Ostatnio trochę błądziłem między systemami i odkryłem bardzo interesującą rzecz. Miałem wtedy w MBRze boot-managera z FreeBSD i chciałem przywrócić NTLDRa - to wrzucam płytę XP-ka piszę w konsoli fdisk /mbr ( tak jak gdzieś czytałem) - nie ma takiego polecenia. Piszę help. JEST - polecenie fixmbr - pewnie to to. Niee pozory mylą - do MBRa wrzucił BTX - Bootloader FreeBSD, który wówczas znajdował się na drugiej partycji. "V for Vista!" chciałoby się krzyknąć ;) PS2. Super! wreszcie aspell sensownie działa( gentoo działał w unicode i nie zbyt przyjemnie się z nim pracowało( trochę źle wyświetlał tekst)