1/16 Zmienne systemowe i użytkownika w skryptach Linux
2/16 1. Wprowadzenie do zmiennych w systemach Unix/Linux

Systemy operacyjne z rodziny Unix i Linux opierają swoje działanie na rozbudowanym systemie zmiennych konfiguracyjnych, które definiują środowisko pracy użytkownika, zachowanie powłoki oraz parametry działających procesów. W przeciwieństwie do systemów Windows, gdzie zmienne środowiskowe mają charakter hierarchiczny z rejestrem jako centralnym repozytorium, w Linuxie dominuje model tekstowy z plikami konfiguracyjnymi i mechanizmami dziedziczenia przez procesy potomne. Ta fundamentalna różnica w architekturze wpływa na sposób zarządzania, wyświetlania i modyfikacji zmiennych.

Zrozumienie mechanizmów zmiennych w systemie Linux jest kluczowe dla administratorów systemów, programistów i wszystkich użytkowników pracujących z linią poleceń. Skrypty powłoki (Bash, sh, zsh) stanowią podstawowe narzędzie automatyzacji w środowiskach serwerowych, a ich efektywne wykorzystanie wymaga biegłej znajomości zarządzania zmiennymi. Linux oferuje również znacznie bardziej rozbudowany model zmiennych niż klasyczne Windows CMD, obejmujący tablice, zmienne asocjacyjne, funkcje ze zmiennymi lokalnymi oraz zaawansowane operacje na ciągach tekstowych.

3/16 2. Architektura zmiennych w systemie Linux

Model zmiennych w systemach Linux opiera się na kilku fundamentalnych koncepcjach, które determinują zachowanie, zasięg i czas życia zmiennych. Zrozumienie tej architektury jest niezbędne dla świadomego zarządzania środowiskiem i pisania efektywnych skryptów.

2.1 Typy zmiennych według zasięgu

W kontekście systemów Linux wyróżniamy następujące kategorie zmiennych, różniące się poziomem dostępności i czasem życia:

  • Zmienne środowiskowe (Environment Variables) - zmienne widoczne dla wszystkich procesów uruchomionych (jako potomków) w systemie, dziedziczone przez procesy potomne. Definiowane na poziomie systemu lub użytkownika i przechowywane w plikach konfiguracyjnych.
  • Zmienne powłoki (Shell Variables) - zmienne dostępne tylko w bieżącej powłoce lub jej podpowłokach, niewidoczne dla innych procesów. Tworzone lokalnie przez użytkownika lub skrypt.
  • Zmienne globalne (Global) - zmienne środowiskowe widoczne dla wszystkich użytkowników i procesów w systemie, definiowane w plikach systemowych (/etc/environment, /etc/profile).
  • Zmienne lokalne (Local) - zmienne definiowane wewnątrz funkcji lub skryptu, niewidoczne poza ich kontekstem.
  • Zmienne readonly - zmienne stałe, których wartość nie może być zmieniona po inicjalizacji.

2.2 Hierarchia i dziedziczenie

Każdy nowo uruchomiony proces w systemie Linux otrzymuje kopię zmiennych środowiskowych od procesu macierzystego. Jest to fundamentalna cecha systemów Unix, zwana fork-exec - proces potomny dziedziczy środowisko rodzica, ale wszystkie modyfikacje dotyczą tylko jego własnej kopii. Oryginalne zmienne procesu macierzystego pozostają niezmienione, chyba że użyto specjalnych mechanizmów komunikacji międzyprocesowej.

# Proces potomny dziedziczy zmienne srodowiskowe
$ export WIADOMOSC="Czesc z rodzica"
$ bash -c 'echo $WIADOMOSC'
Czesc z rodzica
# Zmiany w podpowloce nie wplywaja na rodzica
$ bash -c 'WIADOMOSC="Zmieniona"; echo $WIADOMOSC'
Zmieniona
$ echo $WIADOMOSC
Czesc z rodzica
# Eksport zmiennej czyni ja widoczna dla potomkow
$ export WIADOMOSC
$ bash -c 'echo $WIADOMOSC'
Czesc z rodzica

2.3 Pliki konfiguracyjne i źródła zmiennych

Zmienne środowiskowe w systemie Linux są definiowane w różnych plikach konfiguracyjnych, które są wczytywane w określonej kolejności. Kolejność ta determinuje, która wartość zmiennej ma pierwszeństwo w przypadku wielokrotnej definicji.

  • /etc/environment - plik systemowy zawierający zmienne środowiskowe dla wszystkich użytkowników. Wczytywany przy logowaniu.
  • /etc/profile - skrypt wykonywany dla wszystkich użytkowników podczas logowania (powłoki logowania).
  • /etc/bash.bashrc - plik konfiguracyjny Bash dla wszystkich użytkowników uruchamiających interaktywną powłokę.
  • ~/.bash_profile - plik użytkownika wczytywany przy logowaniu (dla powłok logowania).
  • ~/.bashrc - plik użytkownika wczytywany przy uruchomieniu interaktywnej powłoki nielogowania.
  • ~/.profile - alternatywny plik profilu użytkownika, używany gdy ~/.bash_profile nie istnieje.
4/16 3. Wyświetlanie zmiennych

Linux oferuje kilka poleceń do wyświetlania zmiennych środowiskowych i powłoki. Każde z nich ma nieco inne zastosowanie i zwraca różne typy zmiennych.

3.1 Polecenia env i printenv

Polecenia env i printenv służą do wyświetlania zmiennych środowiskowych. Różnica polega na tym, że env może być użyte również do uruchomienia programu ze zmodyfikowanym środowiskiem, podczas gdy printenv służy wyłącznie do wyświetlania.

# Wyswietl wszystkie zmienne srodowiskowe
$ env
# To samo za pomoca printenv
$ printenv
# Wyswietl konkretna zmienna
$ printenv HOME
/home/uzytkownik
# Wyszukaj zmienne zawierajace okreslony wzorzec
$ env | grep "^PATH"
PATH=/usr/local/bin:/usr/bin:/bin

3.2 Polecenie echo i odwołania do zmiennych

Polecenie echo w połączeniu ze specjalną składnią $NAZWA_ZMIENNEJ służy do wyświetlania wartości zmiennych. Znak dolara informuje powłokę, że ma podstawić wartość zmiennej w miejsce jej nazwy.

# Wyswietl zmienna za pomoca echo
$ echo $HOME
/home/uzytkownik
$ echo $USER
uzytkownik
$ echo $PWD
/home/uzytkownik/Dokumenty
# Wyswietl wiele zmiennych
$ echo "Uzytkownik: $USER, Katalog: $HOME"
Uzytkownik: uzytkownik, Katalog: /home/uzytkownik
# Bezpieczne wyswietlanie (wartosc w cudzyslowach)
$ echo "$HOME"
/home/uzytkownik

3.3 Polecenie set

Polecenie set bez parametrów wyświetla wszystkie zmienne powłoki (zarówno te środowiskowe jak i lokalne), funkcje powłoki oraz ustawienia powłoki. Jest to znacznie szerszy zestaw niż oferowany przez env.

# Wyswietl wszystkie zmienne i funkcje powloki
$ set
# set z argumentem - pokazuje zmienne zaczynajace sie od podanego ciagu
$ set | grep "^H"
# Lista wszystkich zdefiniowanych zmiennych
$ declare -p
5/16 4. Kompletna lista zmiennych systemowych Linux

Systemy Linux definiują szereg standardowych zmiennych środowiskowych i powłoki, które są ustawiane przez system init, menedżera logowania i powłokę. Poniżej przedstawiono najważniejsze z nich wraz ze szczegółowym opisem ich zastosowania.

4.1 Zmienne dotyczące użytkownika i sesji

  • HOME - ścieżka do katalogu domowego bieżącego użytkownika. Wskazuje lokalizację przechowywania plików użytkownika, plików konfiguracyjnych powłoki (.bashrc, .profile) oraz podfolderów (Dokumenty, Pulpit itp.). Jest to fundamentalna zmienna używana w niemal każdym skrypcie operującym na plikach użytkownika.
  • USER - nazwa bieżącego zalogowanego użytkownika. Przydatna do personalizacji komunikatów, logowania działań i określania uprawnień.
  • UID - numeryczny identyfikator użytkownika (User ID). Jest to zmienna powłoki Bash (tylko do odczytu), ustawiana automatycznie. W przeciwieństwie do nazwy, UID jest stały dla danego konta i nie zmienia się przy zmianie nazwy użytkownika.
  • GID - numeryczny identyfikator głównej grupy użytkownika (Group ID). W systemach Linux nie występuje jako samodzielna zmienna środowiskowa - grupę można odczytać za pomocą polecenia id -g lub przez zmienną powłoki GROUPS.
  • GROUPS - lista identyfikatorów grup, do których należy użytkownik (oddzielonych spacjami). Jest to zmienna powłoki Bash (tablica), niedostępna jako zmienna środowiskowa.
  • SHELL - pełna ścieżka do domyślnej powłoki użytkownika (np. /bin/bash, /bin/zsh, /bin/sh). Określa powłokę uruchamianą przy logowaniu.
  • LOGNAME - nazwa użytkownika używana do logowania. Może różnić się od USER w niektórych kontekstach.
  • PWD - aktualny katalog roboczy (Print Working Directory). Automatycznie aktualizowany przy każdym poleceniu cd.
  • OLDPWD - poprzedni katalog roboczy. Umożliwia szybkie przechodzenie między dwoma katalogami za pomocą polecenia cd -.

4.2 Zmienne dotyczące systemu operacyjnego

  • HOSTNAME - nazwa hosta systemu w sieci. Identyfikuje maszynę w środowiskach wielomaszynowych i jest używana w komunikatach, logach i konfiguracjach sieciowych.
  • HOSTTYPE - typ architektury sprzętowej (np. x86_64, i686, armv7l). Pozwala skryptom na dostosowanie zachowania do platformy sprzętowej.
  • MACHTYPE - pełna specyfikacja platformy sprzętowej i systemowej (format tupli). Jest to zmienna powłoki Bash, a nie zmienna środowiskowa.
  • OSTYPE - typ systemu operacyjnego (np. linux-gnu, darwin dla macOS). Jest to zmienna powłoki Bash, niedostępna jako zmienna środowiskowa.
  • TERM - typ terminala lub emulatora terminala (np. xterm-256color, vt100, screen). Określa zdolności wyświetlania i sekwencje sterujące.
  • DISPLAY - numer wyświetlacza X11 dla aplikacji graficznych. W formacie :0 dla lokalnego wyświetlacza, :10.0 dla zdalnych.
  • TERMINFO - ścieżka do bazy danych opisów terminali.

4.3 Zmienne dotyczące ścieżek i katalogów

  • PATH - lista katalogów (oddzielonych dwukropkami) przeszukiwanych przy uruchamianiu poleceń bez podawania pełnej ścieżki. Jest to najważniejsza zmienna dla funkcjonalności systemu.
  • CDPATH - lista katalogów przeszukiwanych przez polecenie cd. Umożliwia szybkie przechodzenie do często używanych lokalizacji.
  • MANPATH - lista katalogów zawierających strony podręcznika man.
  • INFOPATH - lista katalogów zawierających dokumentację info.
  • LD_LIBRARY_PATH - lista katalogów przeszukiwanych przez linker dynamiczny przy ładowaniu bibliotek współdzielonych.
  • LD_PRELOAD - lista bibliotek ładowanych przed wszystkimi innymi (używane do debugowania i wstrzykiwania kodu).

4.4 Zmienne dotyczące lokalizacji i języka

  • LANG - domyślne ustawienia lokalizacji i języka dla wszystkich kategorii LC_. Określa kodowanie znaków, format daty, liczb i walut.
  • LC_ALL - nadpisuje wszystkie ustawienia lokalizacji. Jeśli ustawiona, ma pierwszeństwo przed LANG i innymi zmiennymi LC_.
  • LC_MESSAGES - język komunikatów programów.
  • LC_TIME - format daty i czasu.
  • LC_NUMERIC - format liczb (separator dziesiętny).
  • LC_COLLATE - kolejność sortowania znaków.
  • TZ - strefa czasowa (np. Europe/Warsaw, America/New_York).

4.5 Zmienne dotyczące sesji powłoki

  • BASH - pełna ścieżka do pliku wykonywalnego powłoki Bash.
  • BASH_VERSION - wersja powłoki Bash w formacie czytelnym dla człowieka.
  • BASH_VERSINFO - szczegółowa wersja Bash w formacie tablicowym.
  • SHELLOPTS - lista włączonych opcji powłoki (oddzielona dwukropkami).
  • IFS - separator pól wejściowych (Internal Field Separator). Domyślnie spacja, tabulator, nowa linia.
  • PS1 - definicja głównego znaku zachęty powłoki. Może zawierać informacje o użytkowniku, hoście, katalogu, gałęzi git.
  • PS2 - znak zachęty dla kontynuacji wiersza (gdy polecenie nie zostało zamknięte).
  • PS4 - znak zachęty dla debugowania (tryb set -x).

4.6 Zmienne historii poleceń

  • HISTCONTROL - kontroluje, co jest zapisywane do historii (ignoredups, ignorespace, ignoreboth).
  • HISTIGNORE - wzorce poleceń pomijanych w historii.
  • HISTFILE - ścieżka do pliku historii poleceń (domyślnie ~/.bash_history).
  • HISTSIZE - maksymalna liczba poleceń zapisywana w historii bieżącej sesji.
  • HISTFILESIZE - maksymalna liczba linii w pliku historii.
  • HISTTIMEFORMAT - format znacznika czasu dla historii (np. "%Y-%m-%d %H:%M:%S").

4.7 Zmienne poczty

  • MAIL - ścieżka do skrzynki pocztowej użytkownika. Powłoka sprawdza ten plik i informuje o nowych wiadomościach.
  • MAILCHECK - interwał (w sekundach) sprawdzania skrzynki pocztowej. Domyślnie 60.
6/16 5. Tworzenie i modyfikacja zmiennych

Tworzenie zmiennych w powłokach uniksowych wymaga zrozumienia fundamentalnej różnicy między zmiennymi powłoki a zmiennymi środowiskowymi. Zmienne powłoki istnieją tylko w bieżącej powłoce i nie są dziedziczone przez procesy potomne. Aby zmienna była widoczna dla innych programów, musi zostać wyeksportowana do środowiska.

5.1 Podstawowe operacje na zmiennych

Proste przypisanie zmiennej tworzy zmienną powłoki, która nie jest eksportowana do środowiska. Aby zmienna stała się zmienną środowiskową, należy użyć polecenia export.

# Tworzenie zmiennej powloki (lokalna)
$ MOJA_ZMIENNA="tekst"
$ echo $MOJA_ZMIENNA
tekst
# Zmienna nie jest widoczna dla podpowloki
$ bash -c 'echo $MOJA_ZMIENNA'
(puste)
# Eksport zmiennej - teraz widoczna dla potomkow
$ export MOJA_ZMIENNA
$ bash -c 'echo $MOJA_ZMIENNA'
tekst
# Eksport i przypisanie w jednej linii
$ export INNA_ZMIENNA="wartosc"
$ bash -c 'echo $INNA_ZMIENNA'
wartosc

5.2 Polecenie export i jego opcje

Polecenie export służy nie tylko do eksportowania zmiennych, ale również do wyświetlania listy eksportowanych zmiennych oraz tworzenia zmiennych tylko do odczytu.

# Wyswietl liste eksportowanych zmiennych
$ export -p
# Usun atrybut eksportu (zmienna pozostaje w powloce, ale nie bedzie dziedziczona)
$ export -n MOJA_ZMIENNA
# Eksport ze specjalnym atrybutem (tylko do odczytu)
$ declare -r -x STALA_WARTOSC="niemodyfikowalna"
$ STALA_WARTOSC="nowa"
bash: STALA_WARTOSC: readonly variable

5.3 Polecenie unset

Polecenie unset usuwa zmienną z bieżącej powłoki. Może być użyte zarówno dla zmiennych powłoki, jak i zmiennych środowiskowych (ale tylko w bieżącej powłoce, nie w procesach potomnych).

# Usun zmienna
$ MOJA_ZMIENNA="do usuniecia"
$ unset MOJA_ZMIENNA
$ echo $MOJA_ZMIENNA
(puste)
# Nie mozna usunac zmiennych tylko do odczytu
$ readonly STALA="wartosc"
$ unset STALA
bash: unset: STALA: cannot unset: readonly variable

5.4 Polecenie readonly

Polecenie readonly oznacza zmienną jako "tylko do odczytu", co uniemożliwia jej późniejszą modyfikację lub usunięcie. Jest to przydatne do definiowania stałych konfiguracyjnych w skryptach.

# Zdefiniuj zmienna tylko do odczytu
$ readonly WERSJA_APLIKACJI="1.0.0"
$ readonly KATALOG_GLOWNY="/opt/aplikacja"
$ echo $WERSJA_APLIKACJI
1.0.0
# Proba modyfikacji konczy sie bledem
$ WERSJA_APLIKACJI="2.0.0"
bash: WERSJA_APLIKACJI: readonly variable
# Lista zmiennych tylko do odczytu
$ readonly -p
7/16 6. Zmienne lokalne w skryptach Bash

W powłoce Bash zmienne są domyślnie "globalne" dla bieżącej powłoki. Jednak wewnątrz funkcji można jawnie definiować zmienne lokalne, które nie będą kolidować ze zmiennymi o tych samych nazwach w innych częściach skryptu. Polecenie local ogranicza zasięg zmiennej do bieżącej funkcji.

6.1 Polecenie local

Polecenie local tworzy zmienną lokalną wewnątrz funkcji. Zmienna ta istnieje tylko w czasie wykonywania funkcji i jest niewidoczna poza nią. Jest to fundamentalny mechanizm izolacji zmiennych w profesjonalnych skryptach Bash.

# Przyklad zmiennych lokalnych w funkcji
funkcja_testowa() {
local zmienna_lokalna="Jestem lokalna"
echo "Wewnatrz funkcji: $zmienna_lokalna"
echo "Zmienna globalna: $zmienna_globalna"
}
zmienna_globalna="Jestem globalna"
funkcja_testowa
Wewnatrz funkcji: Jestem lokalna
Zmienna globalna: Jestem globalna
$ echo $zmienna_lokalna
(puste - zmienna nie istnieje poza funkcja)
$ echo $zmienna_globalna
Jestem globalna

6.2 Zmienne lokalne a modyfikacja zmiennych globalnych

Wewnątrz funkcji można zarówno odczytywać, jak i modyfikować zmienne globalne. Jednak tworzenie zmiennej lokalnej o tej samej nazwie, co zmienna globalna, tymczasowo "zasłania" tę globalną w zakresie funkcji.

# Modyfikacja zmiennej globalnej wewnatrz funkcji
LICZNIK=0
inkrementuj() {
LICZNIK=$((LICZNIK + 1))
}
inkrementuj
echo $LICZNIK
1
# Zmienna lokalna "zaslania" globalna
ZMIENNA="globalna"
funkcja_z_lokalna() {
local ZMIENNA="lokalna"
echo "Wewnatrz: $ZMIENNA"
}
funkcja_z_lokalna
Wewnatrz: lokalna
$ echo "Na zewnatrz: $ZMIENNA"
Na zewnatrz: globalna

6.3 Deklaracje zmiennych - declare i typeset

Polecenia declare i typeset (typeset jest przestarzałym synonimem declare) pozwalają na definiowanie zmiennych z określonymi atrybutami. Są one szczególnie przydatne do tworzenia zmiennych tablicowych, zmiennych tylko do odczytu oraz zmiennych całkowitoliczbowych.

# Deklaracja zmiennej calkowitoliczbowej
$ declare -i CALKOWITA=42
$ CALKOWITA="tekst"
$ echo $CALKOWITA
0
# Deklaracja zmiennej tablicowej
$ declare -a MOJA_TABLICA
$ MOJA_TABLICA=(element1 element2 element3)
# Deklaracja zmiennej asocjacyjnej (tylko Bash 4+)
$ declare -A SLOWNIK
$ SLOWNIK[klucz1]="wartosc1"
$ SLOWNIK[klucz2]="wartosc2"
# Deklaracja zmiennej srodowiskowej
$ declare -x MOJE_SRODOWISKO="wartosc"
# Deklaracja zmiennej tylko do odczytu
$ declare -r STALA="wartosc"
8/16 7. Zmienne specjalne powłoki Bash

Bash udostępnia szereg zmiennych specjalnych, które mają predefiniowane znaczenie i są automatycznie ustawiane przez powłokę. Zmienne te pozwalają na dostęp do argumentów skryptu, informacji o procesie, kodów wyjścia i innych danych kontekstowych.

7.1 Parametry pozycyjne

Parametry pozycyjne przechowują argumenty przekazane do skryptu lub funkcji. Indeksowanie zaczyna się od 1 (nie od 0), a specjalna zmienna $0 zawiera nazwę skryptu.

# Skrypt: args.sh
#!/bin/bash
# Wywolanie: ./args.sh arg1 arg2 arg3
echo "Nazwa skryptu: $0"
echo "Pierwszy argument: $1"
echo "Drugi argument: $2"
echo "Trzeci argument: $3"
echo "Dziesiaty argument: ${10}"
# Wynik wywolania: ./args.sh plik.txt kopia.log /backup
Nazwa skryptu: ./args.sh
Pierwszy argument: plik.txt
Drugi argument: kopia.log
Trzeci argument: /backup

7.2 Zmienne specjalne

Oprócz parametrów pozycyjnych, Bash udostępnia szereg zmiennych specjalnych z predefiniowanym znaczeniem:

# $# - liczba argumentow
echo "Liczba argumentow: $#"
# $@ - wszystkie argumenty jako osobne slowa
for arg in "$@"; do
echo "Argument: $arg"
done
# $* - wszystkie argumenty jako pojedyncze slowo
echo "Wszystkie: $*"
# $$ - PID biezacego procesu (skryptu)
echo "PID: $$"
# $! - PID ostatniego procesu uruchomionego w tle
sleep 60 &
echo "PID procesu w tle: $!"
# $? - kod wyjscia ostatniego polecenia
ls /etc/passwd
echo "Kod wyjscia: $?"
0
ls /etc/nieistniejacy
echo "Kod wyjscia: $?"
2
# $- - biezace opcje powloki
echo "Opcje powloki: $-"

7.3 Rozszerzenia parametrów

Bash oferuje zaawansowane mechanizmy rozszerzania parametrów, które pozwalają na operacje takie jak wartości domyślne, warunkowe przypisania, manipulacje ciągami i wiele innych.

# Wartosc domyslna jesli zmienna jest pusta lub nieustawiona
$ echo ${ZMIENNA:-"domyslna"}
domyslna
# Przypisz wartosc domyslna jesli zmienna jest pusta
$ echo ${ZMIENNA:="nowa"}
nowa
$ echo $ZMIENNA
nowa
# Dlugosc zmiennej
$ TEKST="Ala ma kota"
$ echo ${#TEKST}
11
# Wycinanie prefixu i suffixu
$ PLIK="/home/user/dokument.txt"
$ echo ${PLIK##*/} # usun najdluzszy prefix */ = dokument.txt
$ echo ${PLIK%/*} # usun najkrotszy suffix /* = /home/user
$ echo ${PLIK:5:4} # substring od 5, dlugosc 4 = /use
9/16 8. Tablice w Bash

Bash wspiera tablice jednowymiarowe (indeksowane liczbami) oraz tablice asocjacyjne (indeksowane ciągami znaków, dostępne od Bash 4). Tablice pozwalają na przechowywanie wielu wartości pod jedną nazwą i są niezastąpione przy przetwarzaniu list danych.

8.1 Deklaracja i operacje na tablicach

Tablice w Bash można tworzyć na wiele sposobów: przez bezpośrednie przypisanie listy wartości, przez przypisanie pojedynczych elementów lub przez deklarację z użyciem declare.

# Tworzenie tablicy
$ MOJA_TABLICA=(element1 element2 element3)
$ echo "${MOJA_TABLICA[0]}"
element1
$ echo "${MOJA_TABLICA[@]}"
element1 element2 element3
# Indeksowanie tablicy
$ MOJA_TABLICA[5]="element o indeksie 5"
$ echo "${MOJA_TABLICA[5]}"
element o indeksie 5
# Liczba elementow tablicy
$ echo "${#MOJA_TABLICA[@]}"
4
# Dlugosc elementu o danym indeksie
$ echo "${#MOJA_TABLICA[0]}"
8
# Dodawanie elementow
$ MOJA_TABLICA+=(nowy1 nowy2)
$ echo "${MOJA_TABLICA[@]}"
element1 element2 element3 element o indeksie 5 nowy1 nowy2
# Usuniecie elementu
$ unset MOJA_TABLICA[1]
$ echo "${MOJA_TABLICA[@]}"
element1 element3 element o indeksie 5 nowy1 nowy2

8.2 Tablice asocjacyjne

Tablice asocjacyjne (słowniki) pozwalają na indeksowanie elementów ciągami znaków zamiast liczbami. Wymagają deklaracji z użyciem declare -A i są dostępne w Bash w wersji 4 i nowszych.

# Deklaracja tablicy asocjacyjnej
$ declare -A KONTYNENTY
$ KONTYNENTY[Polska]="Europa"
$ KONTYNENTY[Japonia]="Azja"
$ KONTYNENTY[Brazylia]="Ameryka Poludniowa"
# Dostep do elementow
$ echo "${KONTYNENTY[Polska]}"
Europa
# Lista wszystkich kluczy
$ echo "${!KONTYNENTY[@]}"
10/16 9. Zasięg zmiennych w praktyce

Zrozumienie zasięgu zmiennych jest kluczowe dla pisania poprawnych skryptów. W tej sekcji omówiono praktyczne aspekty zarządzania zasięgiem, w tym hierarchię, dziedziczenie i techniki przekazywania wartości między zakresami.

9.1 Hierarchia zasięgów

W powłoce Bash można wyróżnić następujące poziomy zasięgu, uporządkowane od najszerszego do najwęższego: zmienne środowiskowe (widoczne dla wszystkich procesów), zmienne globalne skryptu (widoczne w całym skrypcie), zmienne lokalne funkcji (widoczne tylko w danej funkcji).

# Demonstracja hierarchii zasiegow
#!/bin/bash
# Zmienna globalna skryptu
GLOBALNA="Jestem globalna"
funkcja_zewnetrzna() {
echo "Funkcja zewnetrzna widzi: $GLOBALNA"
funkcja_wewnetrzna
}
funkcja_wewnetrzna() {
local LOKALNA="Jestem lokalna"
echo "Funkcja wewnetrzna widzi: $GLOBALNA i $LOKALNA"
echo "Ale nie widzi zmiennej_z_funkcji_zewnetrznej: ${zmienna_zewnetrzna:-nie istnieje}"
}
funkcja_zewnetrzna
Funkcja zewnetrzna widzi: Jestem globalna
Funkcja wewnetrzna widzi: Jestem globalna i Jestem lokalna
Ale nie widzi zmiennej_z_funkcji_zewnetrznej: nie istnieje

9.2 Zmienne środowiskowe a podpowłoki

Uruchomienie polecenia w podpowłoce (za pomocą nawiasów okrągłych lub bash -c) tworzy nowy proces z własną kopią środowiska. Zmiany w podpowłoce nie wpływają na proces macierzysty.

# Podpowloka z (nawiasy)
$ ZMIENNA="przed"
$ ( ZMIENNA="zmieniona_w_podpowloce"; echo $ZMIENNA )
zmieniona_w_podpowloce
$ echo $ZMIENNA
przed
# Uzycie export dla dziedziczenia przez podpowloke
$ export ZMIENNA
$ ( echo $ZMIENNA )
przed
# Uzycie subshella do izolacji zmian
$ ( cd /tmp && pwd )
$ pwd
/home/uzytkownik (katalog nie zostal zmieniony!)

9.3 Przekazywanie wartości między zakresami

Aby przekazać wartość zmiennej lokalnej na zewnątrz funkcji lub podpowłoki, można użyć kilku technik: echo z subshell i przechwyceniem wyjścia, przekazanie przez zmienną globalną lub przekazanie przez referencję (dostępne w Bash 4+).

# Technika 1: Przechwycenie wyjscia funkcji
funkcja_oblicz() {
local a=5
local b=3
echo $((a + b))
}
WYNIK=$(funkcja_oblicz)
$ echo $WYNIK
8
# Technika 2: Przekazanie nazwy zmiennej do ustawienia (nameref)
funkcja_przypisz() {
local -n ref=$1
ref="nowa_wartosc"
}
ZMIENNA="stara_wartosc"
funkcja_przypisz ZMIENNA
$ echo $ZMIENNA
nowa_wartosc
# Technika 3: Przekazanie przez eval (dla starszych Bash)
funkcja_eval() {
local nazwa=$1
local wartosc=$2
eval "$nazwa='$wartosc'"
}
funkcja_eval MOJA_ZMIENNA "wartosc_z_funkcji"
$ echo $MOJA_ZMIENNA
wartosc_z_funkcji
11/16 10. Konfiguracja zmiennych - pliki systemowe i użytkownika

Zmienne środowiskowe w systemie Linux są definiowane w różnych plikach konfiguracyjnych, które są wczytywane w określonej kolejności przy logowaniu lub uruchomieniu powłoki. Zrozumienie tej kolejności jest kluczowe dla prawidłowej konfiguracji środowiska.

10.1 Pliki systemowe

Pliki systemowe definiują zmienne dla wszystkich użytkowników systemu i są wczytywane przy logowaniu lub uruchomieniu interaktywnej powłoki.

# /etc/environment - zmienne dla wszystkich sesji
# Format: NAZWA=wartosc (bez export!)
# /etc/profile - skrypt dla wszystkich uzytkownikow (logowanie)
# Dodaj PATH dla wszystkich:
export PATH="$PATH:/opt/moje_narzedzia"
# /etc/bash.bashrc - dla interaktywnych powlok Bash
# Aliasy i funkcje dla wszystkich:
alias ll='ls -la'
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S "

10.2 Pliki użytkownika

Pliki w katalogu domowym użytkownika pozwalają na personalizację środowiska bez wpływu na innych użytkowników.

# ~/.bash_profile - wykonywany przy logowaniu powloki logowania
# Zazwyczaj wczytuje ~/.bashrc:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# Dodatkowe ustawienia logowania:
export PATH="$PATH:$HOME/.local/bin"
# ~/.bashrc - wykonywany dla interaktywnych powlok nielogowania
# Aliasy:
alias gs='git status'
alias ..='cd ..'
alias ...='cd ../..'
# Funkcje:
mkcd() { mkdir -p "$1" && cd "$1"; }
# Zmienne uzytkownika:
export EDITOR="vim"
export VISUAL="vim"
# ~/.profile - alternatywa dla ~/.bash_profile
# Uzywany gdy ~/.bash_profile nie istnieje

10.3 Kolejność wczytywania plików

Kolejność wczytywania plików konfiguracyjnych zależy od typu uruchomionej powłoki i jej trybu działania. Zrozumienie tej kolejności pozwala na świadome umieszczanie konfiguracji w odpowiednich plikach.

# Powloka logowania (np. ssh, login w terminalu):
1. /etc/profile
2. ~/.bash_profile, ~/.bash_login lub ~/.profile (pierwszy istniejacy)
# Powloka interaktywna nielogowania (np. nowa karta terminala):
1. /etc/bash.bashrc
2. ~/.bashrc
# Powloka nieinteraktywna (skrypty):
- Wczytuje tylko zmienne z #!/bin/bash -l lub jawnie zrodlowane
# Polecenie source - wczytanie pliku w biezacej powloce:
$ source ~/.bashrc
$ . ~/.bash_aliases
12/16 11. Operacje na ciągach tekstowych

Bash oferuje bogaty zestaw operacji na ciągach tekstowych, od prostego wycinania substringów po zaawansowane wzorce. Te operacje są wykonywane bezpośrednio na zmiennych, bez potrzeby używania zewnętrznych poleceń jak sed czy awk.

11.1 Wycinanie substringów

Operacje wycinania pozwalają na pobranie części ciągu znaków na podstawie pozycji lub wzorca.

# Podstawowe wycinanie
$ TEKST="Ala ma kota"
$ echo ${TEKST:0:3} # od pozycji 0, dlugosc 3
Ala
$ echo ${TEKST:4} # od pozycji 4 do konca
ma kota
$ echo ${TEKST: -4} # 4 ostatnie znaki (spacja przed -!)
kota
# Usuwanie prefixu i suffixu
$ PLIK="/home/user/dokument.txt"
$ echo ${PLIK##*/} # najdluzszy prefix */ = dokument.txt
$ echo ${PLIK#*/} # najkrotszy prefix */ = home/user/dokument.txt
$ echo ${PLIK%%/*} # najdluzszy suffix */ = (puste)
$ echo ${PLIK%/*} # najkrotszy suffix */ = /home/user

11.2 Wyszukiwanie i zamiana

Bash pozwala na wyszukiwanie wzorców i zamianę fragmentów ciągów bezpośrednio w rozszerzeniu parametrów.

# Zamiana pierwszego wystapienia
$ TEKST="ala ma kota, kot jest bialy"
$ echo ${TEKST/kota/psa}
ala ma psa, kot jest bialy
# Zamiana wszystkich wystapien
$ echo ${TEKST//kot/pies}
ala ma piesa, pies jest bialy
# Zamiana prefixu lub suffixu
$ TEKST="/home/user/file.txt"
$ echo ${TEKST/#\/home/\/tmp} # jesli prefix /home, zamien na /tmp
/tmp/user/file.txt
$ echo ${TEKST/%.txt/.bak} # jesli suffix .txt, zamien na .bak
/home/user/file.bak
# Warunkowe przypisanie
$ echo ${NIEISTNIEJACA:-"wartosc domyslna"}
wartosc domyslna
$ ISTNIEJACA="jutro"
$ echo ${ISTNIEJACA:-"wartosc domyslna"}
jutro
13/16 12. Przekazywanie zmiennych między skryptami

Skrypty często muszą komunikować się ze sobą, wymieniając dane lub wyniki. Istnieje kilka standardowych mechanizmów takiej komunikacji w środowisku Linux.

12.1 Eksport i dziedziczenie

Najprostszym mechanizmem jest eksport zmiennej, która zostanie odczytana przez skrypt potomny. Jednak eksport działa tylko w jedną stronę - od rodzica do potomka.

# Skrypt nadrzedny
#!/bin/bash
export MOJA_WARTOSC="dane_z_rodzica"
./skrypt_potomny.sh
# Skrypt potomny (skrypt_potomny.sh)
#!/bin/bash
echo "Otrzymana wartosc: $MOJA_WARTOSC"
Otrzymana wartosc: dane_z_rodzica

12.2 Przekazywanie przez plik

Dla bardziej złożonych danych lub komunikacji w obie strony, można użyć plików tymczasowych. Skrypt źródłowy zapisuje dane, skrypt docelowy je odczytuje.

# Skrypt A - zapisuje dane do pliku
#!/bin/bash
echo "WYNIK=obliczona_wartosc" > /tmp/wynik$$.txt
echo "TIMESTAMP=$(date +%s)" >> /tmp/wynik$$.txt
./skrypt_b.sh
# Skrypt B - odczytuje dane z pliku
#!/bin/bash
source /tmp/wynik$$.txt
$ echo "Otrzymany wynik: $WYNIK"
Otrzymany wynik: obliczona_wartosc
$ rm /tmp/wynik*.txt

12.3 Przekazywanie przez argumenty

Argumenty wiersza poleceń są najczęściej używanym mechanizmem przekazywania danych do skryptów. Można je przekazywać bezpośrednio lub w bardziej zaawansowany sposób.

# Wywolanie z argumentami
./skrypt.sh "wartosc1" "wartosc2" --opcja
# Przekazywanie wszystkich argumentow
skrypt1.sh "arg1" "arg2"
# skrypt1.sh wywoluje skrypt2.sh z tymi samymi argumentami:
./skrypt2.sh "$@"
# Przekazywanie przez eval (dynamiczne wywolanie)
POLECENIE="./skrypt.sh --flag value"
eval $POLECENIE
14/16 13. Najlepsze praktyki i wzorce

Profesjonalne skrypty Bash wymagają stosowania najlepszych praktyk, które zapewniają ich niezawodność, czytelność i przenośność. Poniżej przedstawiono kluczowe zasady i wzorce.

13.1 Szablon profesjonalnego skryptu

Każdy profesjonalny skrypt powinien rozpoczynać się od shebang, deklaracji opcji powłoki, komentarza z metadanymi oraz inicjalizacji środowiska.

#!/bin/bash
# =================================================================
# Skrypt: backup.sh
# Autor: Admin
# Data: 2026-03-26
# Opis: Automatyczna kopia zapasowa danych
# =================================================================
# Wymuszenie natychmiastowego zakonczenia przy bledzie
set -e
# Traktowanie niezdefiniowanych zmiennych jako bledow
set -u
# Blad w potoku zwraca blad
set -o pipefail
# Wylaczenie globbing dla wzorcow
set -f
# Sciezka do katalogu skryptu
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Stale konfiguracyjne
readonly LOG_FILE="/var/log/backup.log"
readonly KATALOG_ZRODLOWY="/home/dane"
# Funkcja logowania
loguj() {
local poziom=$1
shift
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$poziom] $*" | tee -a "$LOG_FILE"
}
# Obsluga bledow
trap 'loguj "ERROR" "Linia $LINENO: $BASH_COMMAND"; exit 1' ERR
# Glowna logika skryptu...

13.2 Konwencje nazewnictwa

Stosowanie spójnych konwencji nazewnictwa znacząco poprawia czytelność kodu i ułatwia jego utrzymanie.

# Stale - WIELKIE_LITERY_Z_PODKRESLNIKAMI
readonly KATALOG_KONFIGURACJI="/etc/app"
readonly MAKSYMALNA_LICZBA_PROB=3
# Zmienne globalne skryptu - WIELKIE_LITERY
ILOSC_PLIKOW=0
KOD_BLEDU=0
# Zmienne lokalne - male_litery_z_podkreslnikami
lokalna_funkcja() {
local plik_tymczasowy=""
local licznik_elementow=0
local wynik_operacji=""
}
# Funkcje - nazwy_czy_slowa_z_podkreslnikami
inicjalizuj_srodowisko() { ... }
sprawdz_wymagania() { ... }
wykonaj_kopie_zapasowa() { ... }
# Tablice - nazwa w liczbie mnogiej z _LIST lub _ARRAY
declare -a PLIKI_DO_KOPII
declare -A USTAWIENIA_SRODOWISKA

13.3 Walidacja zmiennych

Zawsze waliduj zmienne przed ich użyciem, szczególnie w kontekście operacji krytycznych jak dostęp do plików czy modyfikacja systemu.

# Funkcja sprawdzajaca czy zmienna jest ustawiona
czy_ustawiona() {
local nazwa=$1
[[ -z "${!nazwa:-}" ]] && return 1 || return 0
}
if ! czy_ustawiona "KATALOG_ZRODLOWY"; then
echo "BLAD: KATALOG_ZRODLOWY nie jest ustawiony!" >&2
exit 1
fi
# Walidacja sciezki do katalogu
if [[ ! -d "$KATALOG_ZRODLOWY" ]]; then
echo "BLAD: Katalog '$KATALOG_ZRODLOWY' nie istnieje!" >&2
exit 1
fi
# Walidacja wartosci numerycznej
if ! [[ "$WARTOSC" =~ ^[0-9]+$ ]]; then
echo "BLAD: '$WARTOSC' nie jest liczba!" >&2
exit 1
fi
15/16 14. Typowe błędy i jak ich unikać

Znajomość typowych błędów i pułapek związanych ze zmiennymi w Bash pozwala na szybsze debugowanie i pisanie bardziej niezawodnego kodu.

14.1 Problemy z cudzysłowami

Brak cudzysłowów wokoło zmiennych może prowadzić do nieoczekiwanych zachowań, szczególnie gdy wartość zawiera spacje lub inne znaki specjalne.

# BLAD: brak cudzyslowow
$ PLIK="plik z spacjami.txt"
$ ls $PLIK
ls: cannot access 'plik': No such file or directory
# POPRAWNIE: z cudzyslowami
$ ls "$PLIK"
plik z spacjami.txt
# Prawidlowe testy z cudzyslowami
$ if [[ -f "$PLIK" ]]; then
echo "Plik istnieje"
fi

14.2 Problemy z niezdefiniowanymi zmiennymi

W Bash zmienne niezdefiniowane są traktowane jako puste ciągi, co może prowadzić do subtelnych błędów. Opcja set -u wymusza błąd przy użyciu niezdefiniowanej zmiennej.

# BLAD: uzycie niezdefiniowanej zmiennej
$ set -u
$ echo $NIEOKRESLONA
bash: NIEOKRESLONA: unbound variable
# POPRAWNIE: uzyj wartosci domyslnej
$ echo "${NIEOKRESLONA:-pusty}"
pusty
# POPRAWNIE: przypisz wartosc domyslna
$ : ${DOMYSLNA:="wartosc"}
$ echo $DOMYSLNA
wartosc

14.3 Problemy z operatorami porównania

W Bash istnieją różne operatory porównania dla liczb i ciągów. Użycie niewłaściwego operatora prowadzi do nieoczekiwanych wyników.

# BLAD: uzycie operatora numerycznego dla ciagow
$ [[ "10" > "2" ]] && echo "10 > 2" || echo "10 <= 2"
10 <= 2 (BLAD! Porownanie leksykograficzne!)
# POPRAWNIE: uzyj -gt dla liczb
$ [[ 10 -gt 2 ]] && echo "10 > 2" || echo "10 <= 2"
10 > 2
# POPRAWNIE: dla ciagow uzyj > (alfabetyczne)
$ [[ "jablko" > "banan" ]] && echo "jablko > banan"
jablko > banan
# Uzycie (( )) dla wyrazen arytmetycznych
$ if (( 10 > 2 )); then echo "10 > 2"; fi
10 > 2
16/16 15. Podsumowanie

Zmienne w systemach Linux stanowią fundamentalny mechanizm konfiguracji środowiska, przechowywania danych i komunikacji między procesami. Zrozumienie architektury zmiennych - od systemowych poprzez użytkownika, aż po lokalne zmienne skryptów i funkcji - jest niezbędne dla każdego, kto pracuje z linią poleceń lub pisze skrypty automatyzujące zadania.

Pamiętaj o fundamentalnych zasadach: zawsze używaj cudzysłowów wokoło zmiennych zawierających ścieżki lub tekst z białymi znakami, stosuj local wewnątrz funkcji dla zmiennych tymczasowych, eksportuj tylko te zmienne, które muszą być widoczne dla procesów potomnych, używaj set -u i set -e dla lepszego zarządzania błędami, stosuj spójne nazewnictwo i dokumentuj swoje skrypty. Przestrzeganie tych zasad znacząco zwiększy jakość i niezawodność Twoich skryptów powłoki w środowisku Linux.