bash

Z funus.net

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.

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

[edytuj] Zobacz też