bash
GNU Bash to domyślna powłoka w typowych Linuksach. Oczywiście działa też pod innymi Uniksami. Wywodzi się ze starego dobrego sh (Bourne Shell), ale jest znacznie bardziej funkcjonalna, przez to też dość duża.
Spis treści |
[edytuj] Tryby pracy
Bash może pracować w dwóch podstawowych trybach: jako zwykła powłoka (interaktywna bądź w funkcji interpretera skryptów) albo jako tzw. login shell, czyli powłoka uruchamiana automatycznie przez system po zalogowaniu się użytkownika, ewentualnie gdy bash zostanie uruchomiony z opcją -login.
[edytuj] Konfiguracja
Bash posiada szereg plików konfiguracyjnych, z których większość to skrypty shellowe.
[edytuj] Globalne pliki konfiguracyjne
Globalne pliki konfiguracyjne są wspólne dla wszystkich użytkowników. Zwykle są one umieszczane w katalogu /etc.
- /etc/profile
- /etc/bash.logout
- /etc/bash.bashrc
Wszystkie te pliki to skryptu basha.
[edytuj] Pliki konfiguracyjne dla poszczególnych użytkowników
Oddzielny zestaw plików konfiguracyjnych dla każdego użytkownika. Znajdują się one w katalogach domowych poszczególnych użytkowników.
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
- ~/.bash_logout
- ~/.inputrc
Wszystkie te pliki z wyjątkiem ~/.inputrc to skrypty basha.
[edytuj] Kolejność wczytywania plików
Jeśli bash pracuje jako interaktywny login shell, najpierw wczytuje i wykonuje polecenia z pliku /etc/profile. Następnie sprawdza, czy któryś z poniższych plików istnieje w katalogu domowym użytkownika:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
Pierwszy napotkany plik jest wykonywany, pozostałe nie, nawet jeśli istnieją. Natomiast przed zakończeniem wykonywany jest plik ~/.bash_logout.
Gdy bash nie jest login shellem, ale pracuje w trybie interaktywnym, to wykonywane są następujące pliki:
- /etc/bash.bashrc
- ~/.bashrc
Gdy bash jest startowany w trybie interaktywnym wczytywany jest także plik konfiguracyjny biblioteki readline - ~/.inputrc.
Często włącza się plik ~/.bashrc do pliku ~/.bash_profile (albo ~/.bash_login, albo ~/.profile) po to, żeby był on wykonywany przy starcie basha niezależnie do tego, czy pracuje on w trybie login shell, czy nie.
[edytuj] Historia
Bash przechowuje historię wprowadzanych poleceń. Dzięki temu można powtórzyć któreś z poprzednich bez konieczności jego ponownego wpisywania. Historia przed zakończeniem procesu basha jest zapisywana w pliku ~/.bash_history. Przy ponownym uruchomieniu bash odczytuje historię z tego pliku.
Następujące polecenia pozwalają wpłynąć na sposób obsługi historii poleceń.
HISTFILESIZE=liczba
W pliku z historią będzie przechowywane nie więcej niż liczba wierszy.
HISTSIZE=liczba
Podczas pracy bash będzie pamiętać nie więcej niż liczba ostatnich poleceń.
HISTCONTROL=ignorespace|ignoredups|ignoreboth
Przypisanie jednej z wymianionych wartości zmiennej HISTCONTROL powoduje, że bash nie będzie zapamiętywał w historii niektórych poleceń:
- ignorespace - ignorowane będą wprawadzone polecenia rozpoczynające się od spacji
- ignoredups - ignorowane będą polecenia identyczne z ostatnio zapamiętanym
- ignoreboth - ignorowane są zarówno powtarzające się, jak i rozpoczynające się od spacji polecenia.
shopt -s histappend
Właczenie opcji histappend spowoduje, że bash przy wychodzeniu dołączy historię poleceń na koniec pliku ~/.bash_history. Bez tej opcji dotychczasowa zawartość pliku zostanie nadpisane. Na ogół uruchamiamy więcej niż jedną sesję powłoki równocześnie, więc warto włączyć tę opcję.
[edytuj] Klawisze edycyjne
Wykaz podstawowych klawiszy edycyjnych przy domyślnej konfiguracji.
| klawisz | znaczenie |
|---|---|
| ctrl-b | przesuń kursor o jeden znak w lewo (backward) |
| ctrl-f | przesuń kursor o jeden znak w prawo (forward) |
| ctrl-a | przenieś kursor na początek wiersza |
| ctrl-e | przenieś kursor na koniec wiersza (end) |
| ctrl-t | zamień miejscami znak pod kursorem i poprzedni |
| ctrl-d | usuń znak pod kursorem |
| ctrl-h | usuń znak na lewo od kursora |
| ctrl-w | usuń słowo na lewo od kursora |
| ctrl-k | usuń znaki od kursora do końca wiersza |
| ctrl-u | usuń znaki od początku wiersza do kursora |
| ctrl-p | poprzedni wiersz (previous) |
| ctrl-n | następny wiersz (next) |
| ctrl-r | wyszukiwanie w historii wstecz (reverse search) |
| ctrl-s | wyszukiwanie w historii w przód (search) |
[edytuj] Wykrywanie trybu interaktywnego
Czasami zachodzi potrzeba rozróżnienia, czy bash działa w trybie interaktywnym, czy nie. Ważne jest, by skrypty startowe powłoki nie wypisywały żadnych komunikatów, jeśli nie działa ona w trybie interaktywnym. Niezastosowanie się do tego może, w szczególności, uniemożliwić poprawne działanie polecenia scp – programu do kopiowania plików z i do zdalnych systemów, wchodzącego w skład SSH.
Testem na pracę w trybie interaktywnym może być obecność zmiennej PS1, czyli prompt basha. Często jednak użytkownicy w swoich skryptach startowych bezwarunkowo przypisują coś tej zmiennej. Lepiej więc sprawdzić specjalną zmienną z flagami basha: $-. Jeśli wartość tej zmiennej zawiera literę i to znaczy, że działamy w trybie interaktywnym. Sprawdzić to można na przykład tak:
test "${-#*i}" = "$-" || echo tryb interaktwyny
[edytuj] Programmable completion
Taki dziwaczny ficzer dodano parę lat temu do basha: gdy naciskasz tab żeby skompletować polecenie, ścieżkę czy cokolwiek, może zostać wywołana cała kaskada skryptów i filtrów, które będą mogły zrobić różne cuda. Przerost formy nad treścią, moim skromnym zdaniem, bardziej mi to przeszkadza, niż pomaga.
Otóż uwzględniono szereg programów i poleceń i zaprogramowano tak, by klawisz tab rozwijał tylko ścieżki do odpowiednich plików. Na przykład wpisanie tar xzvf i naciśnięcie tab zaproponuje pliki kończące się na .gz, ale pominie te kończące się na .bz2. Z pozoru fajne i pożyteczne, ale tak naprawdę to głupie, zawężające podejście. Przykład: xine obsługuje format flv, ale tego nie uwzględniono, więc bash nie uzupełnia mi ścieżek do plików .flv.
Drugi przykład. Często kompilując pakiety źródłowe korzystałem z taba, żeby uzupełnić ścieżki, np wpisując: ./configure --prefix=/usr/local/opt/x (tab). Ale z tym programmagble completion to nie działa! Nie uwzględniono, że ścieżka może być podana bezpośrednio po znaku "=". Podobnie z poleceniem: make install DESTDIR=/usr/local/stow/x (tab).
Tak więc jak dla mnie ten cały ficzer przynosi więcej szkody niż pożytku. Dlatego go wyłączam. A jak to zrobić? Całe to badziewie jest w pliku /etc/bash_completion, więc jego usunięcie byłoby radykalnym rozwiązaniem problemu. Mniej drastyczne jest przeedytowanie swojego ~/.bashrc i wywalenie instrukcji wczytującej /etc/bash_completion. Natomiast żeby to wyłączyć w bieżącym shellu należy użyć polecenia complete -r.
[edytuj] Tablice asocjacyjne
Dopiero niedawno odkryłem, że prócz zwykłych tablic indeksowanych liczbami, bash obsługuje także tablice asocjacyjne, indeksowane stringami. W przeciwieństwie do tych pierwszych konieczne jest ich zadeklarowanie, np.
declare -A mapa
Następnie można używać ich analogicznie, jak zwykłych, indeksowanych tablic (jednak z tą różnicą, że napisy znakowe w nawiasach nie są interpretowane jak nazwy zmiennych, z których pobiera się wartość indeksu):
$ mapa[czarna]=polewka
$ mapa[czerwony]=pazdziernik
$ echo "rozmiar mapy: ${#mapa[@]}"
rozmiar mapy: 2
$ kolor=czarna
$ echo "mapa[kolor]: ${mapa[kolor]}"
mapa[kolor]:
$ echo "mapa[$kolor]:${mapa[$kolor]}"
mapa[czarna]:polewka
Listę kluczy (czy też indeksów w przypadku tablicy indeksowanej) można uzyskać specjalnym podstawieniem "${!nazwa[@]}". Na przykład:
$ echo "dostępne kolory: ${!mapa[@]}"
dostępne kolory: czarna czerwony
Tablice asocjacyjne pojawiły się w wersji 4.0 basha.