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).

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. :)

Zenwalk 5.2

3 komentarze

Ostatnio sporo eksperymentowałem z różnymi środowiskami - najpierw GNOME, a potem ciut za ciężkie na mój sprzęt(Athlon XP 1700+, 512MB RAM) KDE4, którego jedyną zaletą, moim skromnym zdaniem , jest Amarok. Trochę się poinstalowało śmiecia, więc stwierdziłem, że to dobry moment, żeby spróbować czegoś nowego. Postanowiłem wybrać Zenwalka. Przede wszystkim, że bazuje na slackware i korzysta z niesprawdzonego jeszcze przeze mnie XFCE, ale też hasło "Ever tried zen computing?" nie pozostało bez znaczenia. :)

Na początek instalacja. Tu nie ma się zbytnio nad czym rozpisywać. Instalator jak instalator. Tekstowy, a jednak w ładnej oprawie(framebuffer jak sądzę). Na tym etapie zdziwił mnie fakt iż system ten, podobnie jak poprzednio przeze mnie używany Arch, traktuje wszystkie dyski jako SCSI, co objawia się się nietypowymi nazwami urządzeń(/dev/sdxn i /dev/srn). Dalej jedyną ciekawostką jest ciekawie pomyślana konfiguracja LILO, przypominająca nieco tą z PLD, ale ta jednak jest trochę bardziej rozbudowana.

Potem przyszedł czas na pierwsze bootowanie. Co ciekawe na samym wstępie poczęstował mnie porcją kilku licencji do zaakceptowania(GNU/GPL, Adobe, Intel), a następnie uruchomił alsaconf i całkiem fajny, stworzony w ncurses menedżer użytkowników. Dalej już standard - gdm.

Całkiem ładny wygląd XFCE. Po małym przekonfigurowaniu, bardzo mi odpowiada.

W oczy też się rzuca bardzo dobra szybkość(mniej więcej na równi z Archem). W standardowym zestawie programów niestety nie ma kilku ważnych programów, więc zacząłem od netpkg, menedżera pakietów Zenwalka, a właściwie jego graficznej nakładki. Program wcale przyzwoity, prosty do bólu, nic dodać nic ująć. Szybko wyszukałem seamonkeya(niestety bez polskiej lokalizacji, którą trzeba było doinstalować w klasyczny sposób), następnie mpd, mpc i z braku gmpc, ario, którego wcześniej nie znałem(a szkoda). Mpdscribble niestety musiałem zainstalować ze źródeł, jak również samodzielnie musiałem napisać skrypt startowy dla mpd/mpdscribble, a takze konfigurację. W gruncie rzeczy nic trudnego. Gdy z głośników zaczęła się sączyć muzyka mogłem przejść do konfiguracji. Najpierw XFCE. Wszystko w porządku, tylko szkoda, że nie ma edytora motywów dla GTK. No nic, nauczę się je pisać przynajmniej. :)

Dalej zaskoczył mnie zestaw konfiguratorów zenwalka. Całkiem przyjemnie się ich używa. Szkoda, że kosztem braku /etc/rc.conf. Nie można mieć wszystkiego.

Następnie przyszedł czas na sterowniki NVIDIA. Tu pozytywne zaskoczenie, bo są źródła kernela (Archu jakoś nie mogłem ich znaleźć).

Podsumowując, Zenwalk to bardzo przyjemna, szybka dystrybucja, jak najbardziej pasująca do swojego motta. Większość konfiguracji da się załatwić konfiguratorami(oprócz mpd, cupsa, konfigurowanego przez przeglądarkę; sane, sudo i nvidia). Bardzo duży plus za menedżer pakietów. W jednym zdaniu, jeśli lubisz XFCE, chcesz szybkiego i prostego, a przy okazji całkiem łatwego, systemu to Zenwalk jest zdecydowanie dobrym pomysłem.

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

iTVP pod linuksem? Żaden problem

2 komentarze

Ostatnio było trochę szumu na temat zależności portalu iTVP( choć innych też to dotyczy) od naszej ulubionej firmy i trudności odtwarzania jego zawartości pod innymi systemami niż Windows. Może zmienili to, a mi nic o tym nie wiadomo, ale problemu nie ma, bo wystarczy zainstalować mplayerplug-in. Aż dziwne, że o tym nie słyszałem oO