Pobieranie danych z dialoga

Dialog jest świetnym narzędziem, pomagającym tworzyć pseudograficzne elementy skryptów Basha. O ile samo utworzenie okna dialogowego jest dosyć proste, to pobranie wprowadzonych przez użytkownika danych nie jest już takie oczywiste.

Najważniejsze jest to, że dialog przekazuje owe dane na wyjście błędu, więc odczytanie ich nie jest takie trudne. Nie widzimy go bezpośrednio, zanim nie zakończymy naszego skryptu, można jednak przekierować wyjście błędu do pliku.

WYBRANEMENU="/tmp/$0-$USER"
echo "NIC" > $WYBRANEMENU

dialog --title "Okno menu" \
       --backtitle "Teleturniej." \
       --menu "Wybierz jedno z trzech:" \
       15 50 3 \
       1 "Bramka nr 1" \
       2 "Bramka nr 2" \
       3 "Bramka nr 3" \
       2>"${WYBRANEMENU}"

Co osiągamy? Najpierw przygotowyjemy wspomniany plik. Należy zadbać o to, by jego nazwa była unikalna. Jeżeli kilku użytkowników jednocześnie uruchomiłoby skrypt zapisujący dane do jakiegoś pliku, skutki byłyby zupełnie nieprzewidywalne. Przekierowanie „NIC” do pliku ma dwie zalety: po pierwsze nadpisze go, co by tam wcześniej nie było, a po drugie będziemy mieli jakąś wartość domyślną.

Dialog oczekuje od nas kilku paratetrów:

    • –title: tytuł dialogowego okna,
    • –backtitle: napis pojawiający się w górnym lewym rogu terminala,
    • –menu: rodzaj dialogowego okna i tekst w jego środku,
    • 15 50 3: wymiary okna,
    • 1, 2, 3: nazwy możliwych wyborów, do których będziemy odwoływać się później w naszym skrypcie,
    • „Bramka nr 1”: tekst dla użytkownika programu, żeby wiedział co wybiera,

2>”${WYBRANEMENU}”: standardowe wyjście błędu zostaje zapisane w pliku /tmp/$0-$USER, przy czym $0 zostanie w nazwie pliku zastąpione nazwą pliku skryptu, $USER zaś nazwą uruchamiającego go użytkownika.

Pozostaje tylko odczytać zawartość pliku /tmp/plik-użytkownik. Wystarczy zwykły case:

clear
case $(<"${WYBRANEMENU}") in
  1) echo "ZONK! 1";;
  2) echo "ZONK! 2";;
  3) echo "Wygrałeś 50 złotych!!";;
  "") echo "Anuluj? Poważnie? :(" ;;
esac

Poza starożytną magią, związaną ze sposobem, w jaki Bash potrafi odczytywać zawartość pliku kryjącego się pod zmienną, nie ma tu niczego nadzwyczajnego. Najpierw czyścimy ekran, pozbywając się okna dialogowego. Potem decydujemy co zrobić. Z pliku tymczasowego zostanie odczytana wartość podana w oknie dialogowym: 1, 2, lub 3. Moglibyśmy zamiast liczb wpisać co się nam podoba, ale będzie to widoczne dla użytkownika, więc „kupa”, czy „foo” niestety odpadają. Jeżeli użytkownik wybierze Anuluj, do pliku tymczasowego zostanie przekierowane kompletnie nic i trzeba wziąć to pod uwagę w naszym case.

Na koniec pozostało nam jeszcze usunięcie pliku tymczasowego, przy czym ewentualne błędy nie są dla nas najważniejsze.

rm -f $WYBRANEMENU &> /dev/null

Oczywiście zamiast wypisywania tekstu do terminala możemy uruchamiać nowe okna dialogowe, uruchomić system ponownie, lub zmieniać domyślną Javę. Miłej zabawy.

Arkusz kalkulacyjny w bashu

Tym razem zajmiemy się arkuszem kalkulacyjnym. Zaczniemy od czegoś prostego, na przykład podsumowania roboczogodzin. Najpierw złóżmy arkusz:

$ cat LUTY1 
Roboczogodziny Artura za Luty.
pon:wt:śr:czw:pią:sob:nie
7:6,5:7:8:8:4:0
8:7:7,5:8:8:0:0
7:6:6,5:8:8:4:0
8:7:8:7:8:0:0

Wiersze pliku będą wierszami arkusza, kolumny zaś oddzielimy dwukropkami. Konkretny znak nie jest ważny, ale musi być taki sam w całym w pliku.

Po pierwsze musimy jakoś sformatować arkusz, żeby ładnie wyglądał na wyjściu standardowym:

cut -s -d':' --output-delimiter=$'\t' -f1- LUTY1

Co to w ogóle znaczy? Po kolei:

  • cut jest programem do wyświetlenia fragmentów linii pliku,
  • -s nie wyświetla linii pozbawionych delimitera,
  • -d określa nasz delimiter, którym podzieliliśmy wiersze na komórki,
  • –output-delimiter= określa delimiter, jakim podzielimy dane na standardowym wyjściu
  • $’\t’ to po prostu tabulator,
  • -f określa kolumny, które chcemy wyświetlić (f1- pokaże kolumny od pierwszej do ostatniej),
  • LUTY1 to nazwa pliku do wyświetlenia.

W rezultacie otrzymujemy czytelną tabelę:

pon	wt	śr	czw	pią	sob	nie
7	6,5	7	8	8	4	0       0
8	7	7,5	8	8	0	0       0
7	6	6,5	8	8	4	0       0
8	7	8	7	8	0	0       0

Ciąg dalszy nastąpi…

Man po angielsku

Skoro ostatnio było na temat manuali, to warto wspomnieć o jednym istotnym szczególe: polskich manualach. Są lepsze i gorsze. Tłumaczenie może być technicznie poprawne oraz pozbawione błędów merytorycznych, ale „apropos – przeszukiwanie nazw i opisów stron podręcznika ekranowego” sugeruje użycie automatycznego tłumacza. W takim wypadku, jeżeli czujemy się mocni w angielskim, warto sięgnąć do anglojęzycznej wersji. Wystarczy:

LANG=C man apropos

Korzystam z tego na tyle często, że mam gotowy alias w pliku .bashrc:

men='LANG=C man'

Szukanie w manie

Manual jest zwykle ogromną porcją tekstu, gdzie w bardzo oszczędnej formie opisane są funkcje programu. Zwykle potrzebujemy szybko dostać się do konkretnej informacji, więc najlepiej po prostu skorzystać z wyszukiwarki:

  • /foo (enter)- wyszukuje słowo „foo”,
  • n – szukaj dalej,
  • b – szukaj wstecz,
  • escape+u – wyłącza podświetlanie szukanego słowa.

Jeżeli pracujesz w Debianie polecam zainstalować program less, który czyni przeglądanie manuali nieco wygodniejszym. Przewijanie tekstu kursorami to dla mnie wystarczający powód.

Fonty w xterm

Xterm bywa bardzo przydatny. Na codzień używam gnome-terminala, ale jeżeli program zasypuje nas tekstem na standardowym wyjściu, który niekoniecznie chcemy przeczytać w całości, to gnomowy terminal niepotrzebnie zużywa procesor. Rpmbuild, i ogólnie make, to najlepsze przykłady.

Autorzy xterma wyszli chyba z takiego właśnie założenia, gdyż domyślny font jest tak mały, że nie widać kompletnie niczego. Szczęśliwie dla nas xterm można uruchomić z kilkoma parametrami:

xterm -bg 'black' -fg 'grey' -fa 'Monospace' -fs 14

Kolejno:

  • -bg to kolor tła,
  • -fg to standardowy kolor fonta,
  • -fa to nazwa fonta,
  • -fs to wielkość fonta.

Można oczywiście dodać stosowny alias do .bashrc i mieć to z głowy:

alias xterm='xterm -bg 'black' -fg 'grey' -fa 'Monospace' -fs 14'

 

Upiększamy terminal z powerline

Masz już ustawione wszystkie kolorki w gnome-terminlu? Okno wyświetla już idealny font, a kursor pomryguje zawadiacko, czekając na rm -rf?  Jak to mówią: „no to se jeszcze poczeka,”, bo przed nami trochę pracy.

Powerline to program-nakładka na stare dobre PS1, czyli ciąg znaków, w którym terminal informuje o bieżącym katalogu, numerze IP, zalogowanym użytkowniku, itd… Zwykłem oczywiście modyfikować ów znak zachęty, ale na dobrą sprawę ograniczało się to jednak do kolorowania nazwy użytkownika, żeby się nie myliło.  Zaczytałem o Powerline na blogu Fedory i w głowie miałem tylko „właśnie tego mi brakowało”.

Jak to działa? Po instalacji nie zobaczysz żadnej różnicy, dopóki w bashrc (czy bash_profile) nie dopiszesz kilku linijek:

if [ -f `which powerline-daemon` ]; then
powerline-daemon -q
POWERLINE_BASH_CONTINUATION=1
POWERLINE_BASH_SELECT=1
. /usr/share/powerline/bash/powerline.sh
fi

 

Kiedy teraz na to patrzę widzę, że klauzula if nie jest mi potrzebna, bo nie loguję się zdalnie, ale jak już jest, to niech zostanie. Domyślne zachowanie powerline to wyświetlanie loginu użytkownika na niebieskim tle i dodanie ładnego paska zamiast oddzielania wszystkiego spacjami.

terminal-powerline2

Ładnie i praktycznie zarazem. Sytuacja oczywiście nie wygląda tak różowo w czystej konsoli, prompt minimalnie się krzaczy, ale jest w dalszym ciągu czytelny i w tym przypadku to jest najważniejsze. Najlepsze zostawiłem na koniec: powerline zawiera rozszerzenie do vima, więc warto upiększyć również jego.

terminal-powerline3

I weź tu teraz człowieku używaj Emaksa. 🙂 Podobnie jak w przypadku shella, tu również wystarczy krótka informacja do .vimrc:

python from powerline.vim import setup as powerline_setup
python powerline_setup()
python del powerline_setup
set laststatus=2
set t_Co=256

 

Ciąg dalszy nastąpi…