Tajemnice zmiennych w bashu cz.2: zmienne specjalne

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='> '
Skrócenie tekstu “prompta” pozwala wygodniej wprowadzać długie polecenia

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

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Poprzedni post

PineNote – otwartoźródłowa alternatywa dla Kindle

Następny post

Kdenlive 21.08 – najnowsza wersja otwartoźródłowego edytora wideo

Powiązane posty

Start z Javą i Eclipse, część druga.

Poprawne dane

Tak jak obiecałem w pierwszej części artykułu, w części drugiej na początek opiszę jak należy postępować, aby uniemożliwić wprowadzanie nieprawidłowych danych przez użytkownika. Taki mechanizm zabezpieczający jak łatwo można sobie wyobrazić jest konieczny a wręcz niezbędny do poprawnego działania aplikacji. Aby zabezpieczyć program przed wprowadzaniem niewłaściwych danych do obliczeń, posłużymy się mechanizmem wyjątków – i nie tylko!

Więcej...