Podobnie jak każdy język programowania, bash ma specjalne zmienne, które pozwalają na dostęp do różnych parametrów systemu. Użycie tych zmiennych potrafi bardzo ułatwić życie użytkownika.
W poprzedniej części artykułu opisałem jak przekształcać zawartość zmiennych. Mechanizm ten bardzo ułatwia pisanie skryptów i powoduje, że są one krótsze i mniej skomplikowane.
Tym razem chcę się przyjrzeć specjalnym zmiennym basha. Nazwy tych zmiennych są zarezerwowane i nie można ich użyć do własnych celów. W zamian za to (niewielkie) ograniczenie oferują dostęp do informacji o systemie i bieżącym środowisku. Niektóre z tych zmiennych można modyfikować, inne dostarczają tylko użytecznych informacji. Przyjrzyjmy się im więc.
$0 – nazwa aktualnie wykonywanego skryptu. Wywołana bezpośrednio w konsoli zwraca wartość “bash”.
Zmienna ta przydaje się przy logowaniu zdarzeń, a także przy tworzeniu tekstu pomocy do tworzonego skryptu.
$n (gdzie n to liczba) – argument, który został przekazany do skryptu na n-tej pozycji. Jeśli wywołamy skrypt np.
$ test.sh ala ma kota
to zmienna $1
będzie zawierać “ala”, $2
– “ma”, $3
– “kota”.
W ten sposób można obsłużyć do 9 parametrów. Zazwyczaj nie używa się ich aż tyle, bo to jest po prostu niewygodne, ale gdyby okazało się, że potrzebny jest 10-ty i więcej to zmienne trzeba po prostu zapisać w postaci ${n}
– z klamrami, np. ${10}, ${
11} itd.
$# – liczba argumentów skryptu (nie uwzględniając $0
, wyłącznie argumenty podane przez użytkownika). Przydaje się jeśli chcemy sprawdzić, czy podano wszystkie potrzebne do działania skryptu dane.
$$ – PID (Proces ID) bieżącej powłoki. Dla skryptu jest to PID procesu, w którym został uruchomiony skrypt. Przydaje się to jeśli chce się wymusić zamknięcie skryptu za pomocą polecenia kill
.
$PPID – pid procesu nadrzędnego. Jeśli chcemy zamknąć konsolę, w której został uruchomiony skrypt można to zrobić za pomocą kill -9 $PPID
.
$@ – wszystkie argumenty skryptu jako oddzielne elementy. Tworzą listę, po której można poruszać się np. za pomocą pętli:
for i in $@
do
echo ${i}
done
Bardziej rozbudowany przykład wykorzystania takiej pętli został opisany w artykule Automatyczny help w skryptach bashowych.
$* – wszystkie argumenty skryptu jako jeden ciąg znaków. Rzadziej używana, bo wykorzystanie $@ jest znacznie wygodniejsze.
$? – Kod, z jakim zakończyła się ostatnia operacja. Zazwyczaj “0” informuje, że wszystko jest w porządku, a polecenie zostało wykonane poprawnie. Kod inny niż 0 oznacza kłopoty.
Jeśli tworzymy wiele współpracujących ze sobą skryptów bashowych to każdy z nich może zwracać różne kody wyjścia za pomocą polecenia exit n
. Zmienna $?
pozwala przechwycić ten kod i w ten sposób zareagować na to, co stało się w uprzednio wykonanym poleceniu.
$! – identyfikator ostatnio uruchomionego procesu w tle np. przez dodanie znaku & na końcu polecenia:
$ nano &
[1] 41744
$ echo $!
41744
Dzięki tej zmiennej można zarejestrować taki uruchomiony w tle proces, a następnie – jeśli to będzie konieczna zamknąć go za pomocą polecenia kill:
$ nano & $ HIDDEN=$(echo $!) $ echo $HIDDEN 33 $ kill -9 $HIDDEN [1]+ Killed nano $ bg -bash: bg: current: no such job
$_ – ostatni argument poprzedniego polecenia. Przydaje się, kiedy kolejne polecenie ma operować np. na tym samym pliku, co poprzednie.
$IFS – Internal Field Separator czyli znak, który jest domyślnie używany do oddzielania od siebie elementów. Można go wykorzystać do przetwarzania danych, które są rozdzielane różnymi separatorami np. przecinkami czy średnikami.
$ VAR="jeden,dwa,trzy,cztery" $ for i in $VAR; do echo $i; done jeden,dwa,trzy,cztery $ export IFS=, $ for i in $VAR; do echo $i; done jeden dwa trzy cztery
$PS1 – Tekst poprzedzający znak zachęty. Domyślnie zazwyczaj nazwa użytkownika, maszyny oraz ścieżka do bieżącego katalogu. Danych, które można w tekście zachęty umieścić jest wiele – data, czas, nazwa powłoki itp. Znacznie prościej jest skorzystać z generatora np. http://bashrcgenerator.com/.
Doraźnie można skorzystać z tej zmiennej jeśli ścieżka do bieżącego katalogu staje się zbyt długa i zaczyna przeszkadzać przy wpisywaniu poleceń. Zdarza się to rzadko, ale się zdarza. W takim przypadku można ustawić tę zmienną dla bieżącej konsoli:
PS1='> '

$PWD – bieżąca ścieżka. Jest to odpowiednik polecenia pwd, tyle, że w postaci na bieżąco aktualizowanej zmiennej. Jest to o tyle wygodne, że – korzystając z wiedzy z poprzedniej części artykułu – możemy otrzymać np. samą nazwę bieżącego katalogu
$ echo $PWD
/media/ram/test1/poziom2/poziom3/katalog
$ echo ${PWD##*/}
katalog
oraz inne kombinacje, na które pozwalają przekształcenia zmiennych.
$OLDPWD – ścieżka do katalogu, z którego przeszliśmy do bieżącego za pomocą polecenia cd. Odpowiednik polecenia cd -
.
Dzięki temu można odwołać się w skrypcie do poprzedniego katalogu i np. skopiować z niego potrzebne pliki.
$RANDOM – losowa liczba z przedziału 0 and 32767. Bywa, że potrzebujemy losowej liczby, choćby przy nadawaniu nazw plikom tymczasowym, wtedy można skorzystać z tej zmiennej – na przykład otrzymując losową liczbę z zakresu 1..15
echo $((1 + $RANDOM % 15))
To oczywiście nie wszystkie specjalne zmienne basha. Znacznie więcej można ich znaleźć choćby w Advanced Bash-Scripting Guide. Jednak te wydały mi się najbardziej przydatne i znalazły zastosowanie w wielu skryptach w praktyce.