> For the complete documentation index, see [llms.txt](https://wiki.skylix.pl/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.skylix.pl/vps/komendy-do-ssh.md).

# Komendy do ssh

Komendy do serwera vps

## Podstawowe polecenia

Zbiór komend przydatnych po zalogowaniu się na serwer przez SSH.

### Zarządzanie użytkownikami

Dodanie nowego **konta** (system prosi o hasło, resztę pól możesz pominąć klawiszem **Enter**):

```bash
adduser nazwa_uzytkownika
```

Zmiana **hasła**

```bash
passwd nazwa_uzytkownika
```

Dodanie **użytkownika** do grupy:

```bash
usermod -aG nazwa_grupy nazwa_uzytkownika
```

Lista wszystkich **grup** danego **użytkownika**:

```bash
getent group
groups nazwa_uzytkownika
```

Nadanie uprawnień **administratora** (grupa `sudo` na **Debianie/Ubuntu**):

```bash
usermod -aG sudo nazwa_uzytkownika
```

**Usunięcie** konta (z katalogiem **domowym**):

```bash
deluser --remove-home nazwa_uzytkownika
```

Przełączenie na inne **konto** i sprawdzenie, kim jesteś:

```bash
su nazwa_uzytkownika
whoami
```

Wykonanie **pojedynczego** polecenia z uprawnieniami roota:

```bash
sudo polecenie
```

### Praca z plikami i katalogami

{% hint style="info" %}
Katalogi domowe użytkowników znajdują się w `/home` .
{% endhint %}

<table data-search="false"><thead><tr><th>Cel</th><th>Polecenie</th></tr></thead><tbody><tr><td>Utworzenie katalogu</td><td><code>mkdir nazwa_katalogu</code></td></tr><tr><td>Utworzenie katalogów zagnieżdżonych</td><td><code>mkdir -p a/b/c</code></td></tr><tr><td>Aktualna ścieżka</td><td><code>pwd</code></td></tr><tr><td>Przejście do katalogu</td><td><code>cd /sciezka/do/katalogu</code></td></tr><tr><td>Powrót do katalogu domowego</td><td><code>cd ~</code></td></tr><tr><td>Krok wyżej</td><td><code>cd ..</code></td></tr><tr><td>Lista plików (z ukrytymi)</td><td><code>ls -a</code></td></tr><tr><td>Lista ze szczegółami (prawa, rozmiar, data)</td><td><code>ls -lah</code></td></tr><tr><td>Utworzenie pustego pliku</td><td><code>touch plik.txt</code></td></tr><tr><td>Wyświetlenie zawartości pliku</td><td><code>cat plik.txt</code></td></tr><tr><td>Podgląd końca pliku na żywo</td><td><code>tail -f plik.log</code></td></tr><tr><td>Kopiowanie pliku</td><td><code>cp plik.txt kopia.txt</code></td></tr><tr><td>Kopiowanie katalogu</td><td><code>cp -r katalog katalog_kopia</code></td></tr><tr><td>Przenoszenie / zmiana nazwy</td><td><code>mv stara_nazwa nowa_nazwa</code></td></tr><tr><td>Usunięce pliku</td><td><code>rm plik.txt</code></td></tr><tr><td>Usunięcie katalogu z zawartością</td><td><code>rm -r /sciezka/do/katalogu</code></td></tr><tr><td>Szukanie pliku po nazwie</td><td><code>find / -name "plik.txt"</code></td></tr><tr><td>Szukanie tekstu w plikach</td><td><code>grep -r "szukany tekst" /sciezka</code></td></tr></tbody></table>

{% hint style="warning" %}
`rm -r` kasuje wszystko bez **pytania** i bez kosza. Przed wciśnięciem **Enter** sprawdź ścieżkę.
{% endhint %}

### Edycja plików

Najprostszy edytor w terminalu to `nano`:

```bash
nano plik.txt
```

| Skrót               | Działanie                  |
| ------------------- | -------------------------- |
| Ctrl + O, Enter     | Zapis pliku                |
| Ctrl + X            | Wyjście z edytora          |
| Ctrl + W            | Wyszukiwanie tekstu        |
| Ctrl + K / Ctrl + U | Wycięcie / wklejenie linii |

### Uprawnienia do plików

Właściciel i grupa pliku:

```bash
chown uzytkownik:grupa plik.txt
chown -R uzytkownik:grupa katalog
```

Prawa dostępu (r = odczyt 4, w = zapis 2, x = wykonanie 1):

```bash
chmod 644 plik.txt
chmod 755 skrypt.sh
chmod +x skrypt.sh
```

### Usługi systemowe (systemctl)

```bash
systemctl status nazwa_uslugi     # stan usługi
systemctl start nazwa_uslugi      # uruchomienie
systemctl stop nazwa_uslugi       # zatrzymanie
systemctl restart nazwa_uslugi    # restart
systemctl enable nazwa_uslugi     # autostart po restarcie serwera
systemctl disable nazwa_uslugi    # wyłączenie autostartu
journalctl -u nazwa_uslugi -n 50  # ostatnie 50 linii logów usługi
```

### Aktualizacje i pakiety (Debian / Ubuntu)

```bash
apt update                  # odświeżenie listy pakietów
apt upgrade                 # aktualizacja zainstalowanych pakietów
apt install nazwa_pakietu   # instalacja
apt remove nazwa_pakietu    # usunięcie
```

### Sieć

```bash
ip a                  # adresy IP interfejsów
ping 1.1.1.1          # test połączenia (Ctrl + C kończy)
ss -tulpn             # otwarte porty i procesy, które ich używają
curl -I https://adres # nagłówki odpowiedzi strony
```

### Diagnostyka i monitoring

```bash
df -h        # wolne miejsce na dyskach
du -sh *     # rozmiar plików i katalogów w bieżącej lokalizacji
free -m      # użycie pamięci RAM
uptime       # czas pracy serwera i obciążenie
top          # aktywne procesy w czasie rzeczywistym
ps aux       # lista wszystkich procesów
kill PID     # zatrzymanie procesu o podanym numerze PID
kill -9 PID  # wymuszone zatrzymanie, gdy proces nie reaguje
```

### Przydatne w terminalu

<table data-search="false"><thead><tr><th>Skrót / polecenie</th><th>Działanie</th></tr></thead><tbody><tr><td>Tab</td><td>Autouzupełnianie nazw plików i poleceń</td></tr><tr><td>↑ / ↓</td><td>Przeglądanie historii poleceń</td></tr><tr><td>Ctrl + C</td><td>Przerwanie działającego polecenia</td></tr><tr><td>Ctrl + L lub clear</td><td>Wyczyszczenie ekranu</td></tr><tr><td>history</td><td>Lista wcześniej wpisanych poleceń</td></tr><tr><td>man polecenie</td><td>Instrukcja danego polecenia (wyjście: <code>q</code>)</td></tr><tr><td>polecenie --help</td><td>Krótka pomoc do polecenia</td></tr><tr><td>reboot</td><td>Restart serwera</td></tr></tbody></table>

### Dobrze wiedzieć

* Podczas wpisywania hasła w terminalu nie widać żadnych znaków, nawet gwiazdek. To normalne zachowanie.
* Nazwa użytkownika nie powinna zawierać spacji, polskich znaków ani znaków specjalnych.
* Polecenia na katalogach działają względem bieżącej lokalizacji, więc albo wejdź do katalogu przez `cd`, albo podaj pełną ścieżkę.
* Linux rozróżnia wielkość liter: `Plik.txt` i `plik.txt` to dwa różne pliki.
* Nazwy plików ze spacjami wpisuj w cudzysłowie (`cat "moj plik.txt"`) albo ze znakiem `\` przed spacją.
* Pliki zaczynające się od kropki (np. `.bashrc`) są ukryte i widoczne dopiero po `ls -a`.
* Na co dzień pracuj na zwykłym koncie z `sudo`, a nie bezpośrednio jako `root`. Jedna literówka na koncie roota może uszkodzić system.
* Nie ma cofania usunięcia: po `rm` pliku nie odzyskasz z kosza. Przed ważnymi zmianami zrób kopię (`cp plik plik.bak`).
* Przed edycją plików konfiguracyjnych (np. `/etc/ssh/sshd_config`) zrób ich kopię i po zmianie sprawdź, czy usługa dalej działa. Przy zmianach SSH zostaw otwartą drugą sesję, żeby się nie odciąć od serwera.
* Polecenia `apt` działają na Debianie i Ubuntu. Na innych dystrybucjach (np. AlmaLinux, Rocky) używa się `dnf` lub `yum`.
* Długie polecenie możesz przerwać przez `Ctrl + C`, a jeśli terminal się „zawiesił” po `Ctrl + S`, odblokuje go `Ctrl + Q`.
* Wynik polecenia możesz przekazać do kolejnego znakiem `|`, np. `ls -lah | grep txt`, albo zapisać do pliku przez `>`, np. `df -h > dysk.txt`.

## Zaawansowane polecenia

Zbiór poleceń dla osób, które znają już podstawy i chcą sprawniej administrować serwerem.

{% hint style="info" %}
Przykłady zakładają Debiana lub Ubuntu. Przy innych dystrybucjach mogą różnić się nazwy pakietów i menedżer pakietów.
{% endhint %}

### Potoki i przekierowania

<table data-search="false"><thead><tr><th>Składnia</th><th>Działanie</th></tr></thead><tbody><tr><td><code>polecenie1 | polecenie2</code></td><td>Wynik pierwszego trafia na wejście drugiego</td></tr><tr><td><code>polecenie > plik</code></td><td>Zapis wyniku do pliku (nadpisuje)</td></tr><tr><td><code>polecenie >> plik</code></td><td>Dopisanie wyniku na końcu pliku</td></tr><tr><td><code>polecenie 2> bledy.log</code></td><td>Zapis samych błędów do pliku</td></tr><tr><td><code>polecenie > all.log 2>&#x26;1</code></td><td>Wynik i błędy do jednego pliku</td></tr><tr><td><code>polecenie1 &#x26;&#x26; polecenie2</code></td><td>Drugie polecenie tylko, gdy pierwsze się powiodło</td></tr><tr><td><code>polecenie1 || polecenie2</code></td><td>Drugie polecenie tylko, gdy pierwsze się nie powiodło</td></tr><tr><td><code>polecenie &#x26;</code></td><td>Uruchomienie w tle</td></tr><tr><td><code>polecenie | tee plik</code></td><td>Wynik na ekran i jednocześnie do pliku</td></tr></tbody></table>

```bash
ps aux | grep nginx | grep -v grep
df -h | sort -k5 -hr | head
```

### Przeszukiwanie i przetwarzanie tekstu

#### grep

```bash
grep -rn "error" /var/log/          # szukanie rekurencyjne z numerami linii
grep -i "warning" plik.log          # ignorowanie wielkości liter
grep -v "debug" plik.log            # linie, które NIE zawierają frazy
grep -E "error|fail|critical" plik  # wyrażenie regularne (kilka fraz)
grep -c "404" access.log            # liczba pasujących linii
grep -B2 -A2 "error" plik.log       # 2 linie przed i po dopasowaniu
```

#### awk, sed, cut, sort, uniq

```bash
awk '{print $1}' access.log                     # pierwsza kolumna każdej linii
awk -F: '{print $1}' /etc/passwd                # kolumna z własnym separatorem
awk '{sum+=$3} END {print sum}' dane.txt        # suma trzeciej kolumny

sed 's/stare/nowe/g' plik.txt                   # podmiana (podgląd, bez zapisu)
sed -i 's/stare/nowe/g' plik.txt                # podmiana z zapisem do pliku
sed -i.bak 's/stare/nowe/g' plik.txt            # j.w., z kopią .bak
sed -n '10,20p' plik.txt                        # tylko linie 10-20

cut -d: -f1,3 /etc/passwd                       # wybór kolumn
sort plik.txt | uniq -c | sort -nr | head       # ranking najczęstszych linii
```

Przykład: 10 adresów IP z największą liczbą żądań w logu serwera WWW:

```bash
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
```

### Zaawansowane wyszukiwanie plików

```bash
find /var/www -type f -name "*.php"             # pliki po nazwie
find / -type f -size +500M 2>/dev/null          # pliki większe niż 500 MB
find /var/log -type f -mtime +30                # starsze niż 30 dni
find /home -user jan                            # pliki należące do użytkownika
find . -type f -perm 777                        # pliki z prawami 777
find /tmp -type f -mtime +7 -delete             # usunięcie starych plików
find . -name "*.log" -exec gzip {} \;           # wykonanie polecenia na każdym wyniku
find . -name "*.txt" | xargs grep "fraza"       # przekazanie wyników do innego polecenia
```

{% hint style="danger" %}
Opcji `-delete` oraz `-exec rm` używaj dopiero po sprawdzeniu, co zwraca samo `find` bez nich.
{% endhint %}

### Archiwa i kopie zapasowe

#### tar

```bash
tar -czvf backup.tar.gz /sciezka/do/katalogu    # utworzenie archiwum
tar -xzvf backup.tar.gz                         # rozpakowanie
tar -xzvf backup.tar.gz -C /docelowy/katalog    # rozpakowanie w wybranym miejscu
tar -tzvf backup.tar.gz                         # podgląd zawartości bez rozpakowywania
```

#### rsync i scp

```bash
rsync -avz --progress /zrodlo/ uzytkownik@host:/cel/    # synchronizacja przez SSH
rsync -avz --delete /zrodlo/ /cel/                      # lustro (usuwa nadmiarowe pliki w celu)
rsync -avzn /zrodlo/ /cel/                              # tryb próbny (-n), nic nie zmienia

scp plik.txt uzytkownik@host:/sciezka/                  # wysłanie pliku
scp uzytkownik@host:/sciezka/plik.txt .                 # pobranie pliku
scp -P 2222 -r katalog uzytkownik@host:/sciezka/        # inny port SSH, cały katalog
```

#### Bazy danych (przykłady)

```bash
mysqldump -u root -p nazwa_bazy > baza.sql              # zrzut MySQL / MariaDB
mysql -u root -p nazwa_bazy < baza.sql                  # import zrzutu
pg_dump -U uzytkownik nazwa_bazy > baza.sql             # zrzut PostgreSQL
```

### SSH: klucze, tunele, konfiguracja

```bash
ssh-keygen -t ed25519 -C "opis"                 # generowanie pary kluczy
ssh-copy-id uzytkownik@host                     # wgranie klucza publicznego na serwer
ssh -p 2222 uzytkownik@host                     # połączenie na innym porcie
ssh -i ~/.ssh/moj_klucz uzytkownik@host         # wskazanie klucza prywatnego
```

Tunel lokalny (port 8080 na Twoim komputerze prowadzi do portu 80 serwera):

```bash
ssh -L 8080:localhost:80 uzytkownik@host
```

Plik `~/.ssh/config` pozwala skrócić połączenie do `ssh moj-serwer`:

{% code title="\~/.ssh/config" %}

```
Host moj-serwer
    HostName 203.0.113.10
    User jan
    Port 2222
    IdentityFile ~/.ssh/moj_klucz
```

{% endcode %}

Zalecane ustawienia w `/etc/ssh/sshd_config` po dodaniu klucza:

{% code title="/etc/ssh/sshd\_config" %}

```
PasswordAuthentication no
PermitRootLogin no
```

{% endcode %}

```bash
sshd -t                       # test poprawności konfiguracji
systemctl restart ssh         # zastosowanie zmian (na niektórych systemach: sshd)
```

{% hint style="warning" %}
Przed wyłączeniem logowania hasłem sprawdź, czy logowanie kluczem działa, i zostaw otwartą drugą sesję SSH. Inaczej możesz stracić dostęp do serwera.
{% endhint %}

### Sesje w tle: tmux i screen

Dzięki nim proces działa dalej po zamknięciu połączenia SSH.

```bash
tmux new -s nazwa           # nowa sesja
tmux ls                     # lista sesji
tmux attach -t nazwa        # powrót do sesji
tmux kill-session -t nazwa  # zamknięcie sesji
```

| Skrót w tmux                  | Działanie                                |
| ----------------------------- | ---------------------------------------- |
| `Ctrl + B`, potem `D`         | Odłączenie od sesji (sesja dalej działa) |
| `Ctrl + B`, potem `C`         | Nowe okno                                |
| `Ctrl + B`, potem `N` / `P`   | Następne / poprzednie okno               |
| `Ctrl + B`, potem `%` lub `"` | Podział okna pionowo / poziomo           |

Alternatywnie dla pojedynczego polecenia: `nohup polecenie > wynik.log 2>&1 &`

### Zadania cykliczne (cron)

```bash
crontab -e      # edycja zadań bieżącego użytkownika
crontab -l      # lista zadań
```

Format wpisu: `minuta godzina dzień_miesiąca miesiąc dzień_tygodnia polecenie`

```
0 3 * * *     /home/jan/backup.sh                 # codziennie o 3:00
*/15 * * * *  /home/jan/sprawdz.sh                # co 15 minut
0 4 * * 1     apt update && apt -y upgrade        # w poniedziałki o 4:00
@reboot       /home/jan/start.sh                  # po każdym uruchomieniu serwera
```

{% hint style="info" %}
W crontabie używaj pełnych ścieżek do poleceń i plików, bo cron ma uboższe środowisko niż zwykła sesja SSH. Wynik zadania możesz zapisać do logu: `... >> /var/log/zadanie.log 2>&1`
{% endhint %}

### Własna usługa systemd

{% code title="/etc/systemd/system/moja-aplikacja.service" %}

```ini
[Unit]
Description=Moja aplikacja
After=network.target

[Service]
User=jan
WorkingDirectory=/home/jan/aplikacja
ExecStart=/usr/bin/node /home/jan/aplikacja/index.js
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
```

{% endcode %}

```bash
systemctl daemon-reload                     # wczytanie nowego pliku usługi
systemctl enable --now moja-aplikacja       # włączenie autostartu i uruchomienie
systemctl status moja-aplikacja
systemctl list-units --type=service --state=failed   # usługi, które się wywaliły
systemctl list-timers                       # aktywne timery (alternatywa dla crona)
```

### Logi (journalctl)

```bash
journalctl -u nazwa_uslugi -f               # logi usługi na żywo
journalctl -u nazwa_uslugi --since "1 hour ago"
journalctl -p err -b                        # błędy od ostatniego uruchomienia systemu
journalctl --since "2026-01-01" --until "2026-01-02"
journalctl --disk-usage                     # ile miejsca zajmują logi
journalctl --vacuum-time=14d                # usunięcie logów starszych niż 14 dni
dmesg -T | tail -50                         # komunikaty jądra (sprzęt, dyski, OOM)
last -n 20                                  # ostatnie logowania
lastb | head                                # nieudane próby logowania (root)
```

### Procesy i wydajność

```bash
htop                        # interaktywny podgląd procesów (apt install htop)
ps aux --sort=-%mem | head  # procesy zużywające najwięcej RAM
ps aux --sort=-%cpu | head  # procesy zużywające najwięcej CPU
pgrep -a nginx              # PID-y procesów po nazwie
pkill nazwa_procesu         # zatrzymanie procesów po nazwie
nice -n 10 polecenie        # uruchomienie z niższym priorytetem
renice 10 -p PID            # zmiana priorytetu działającego procesu
lsof -i :80                 # który proces używa portu 80
lsof +D /sciezka            # które procesy trzymają otwarte pliki w katalogu
strace -p PID               # podgląd wywołań systemowych procesu (diagnostyka)
vmstat 1 5                  # statystyki pamięci, CPU i I/O (5 próbek co sekundę)
iostat -x 1 3               # obciążenie dysków (pakiet sysstat)
uptime                      # load average
```

### Dyski i systemy plików

```bash
lsblk                       # drzewo dysków i partycji
lsblk -f                    # j.w., z typem systemu plików i UUID
blkid                       # UUID i typy partycji
mount /dev/sdb1 /mnt/dysk   # zamontowanie partycji
umount /mnt/dysk            # odmontowanie
du -h --max-depth=1 / 2>/dev/null | sort -hr | head   # co zajmuje najwięcej miejsca
df -i                       # zajęte i-węzły (miejsce może się kończyć mimo wolnych GB)
```

Stałe montowanie dysku wymaga wpisu w `/etc/fstab`:

{% code title="/etc/fstab" %}

```
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  /mnt/dysk  ext4  defaults,nofail  0  2
```

{% endcode %}

```bash
mount -a                    # test wpisów fstab bez restartu
```

{% hint style="danger" %}
Błędny wpis w `/etc/fstab` może uniemożliwić start systemu. Dodawaj opcję `nofail` dla dysków dodatkowych i zawsze testuj przez `mount -a`.
{% endhint %}

#### Plik wymiany (swap)

```bash
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
swapon --show
```

Aby swap działał po restarcie, dodaj do `/etc/fstab` linię: `/swapfile none swap sw 0 0`

### Sieć i diagnostyka połączeń

```bash
ip a                        # adresy IP
ip r                        # tablica routingu
ss -tulpn                   # nasłuchujące porty i procesy
ss -s                       # podsumowanie połączeń
ping -c 4 1.1.1.1           # 4 pingi
traceroute adres            # trasa pakietów (lub: mtr adres)
dig domena.pl               # zapytanie DNS
dig +short A domena.pl      # sam adres IP
dig MX domena.pl            # rekordy pocztowe
curl -I https://adres       # nagłówki odpowiedzi
curl -o /dev/null -s -w "%{http_code} %{time_total}s\n" https://adres   # kod i czas odpowiedzi
wget -c https://adres/plik  # pobieranie z wznawianiem
tcpdump -i eth0 port 80     # podgląd ruchu na porcie 80 (root)
nc -zv host 22              # test, czy port jest otwarty
```

### Zapora i zabezpieczenia

#### UFW

```bash
ufw status verbose
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp                        # SSH
ufw allow 80,443/tcp                    # WWW
ufw allow from 203.0.113.5 to any port 3306   # dostęp do bazy tylko z jednego IP
ufw delete allow 80/tcp                 # usunięcie reguły
ufw enable
```

{% hint style="danger" %}
Przed `ufw enable` upewnij się, że port SSH jest dozwolony (`ufw allow 22/tcp` lub Twój własny port). W przeciwnym razie odetniesz się od serwera.
{% endhint %}

#### Fail2ban

```bash
apt install fail2ban
fail2ban-client status                  # lista aktywnych "więzień"
fail2ban-client status sshd             # zablokowane adresy dla SSH
fail2ban-client set sshd unbanip 203.0.113.5   # odblokowanie adresu
```

Własne ustawienia trzymaj w `/etc/fail2ban/jail.local`, a nie w pliku `jail.conf`, bo ten nadpisują aktualizacje.

### Podstawy skryptów Bash

{% code title="backup.sh" %}

```bash
#!/bin/bash
set -euo pipefail

KATALOG="/var/www"
CEL="/backup"
DATA=$(date +%F_%H-%M)

mkdir -p "$CEL"
tar -czf "$CEL/www_$DATA.tar.gz" "$KATALOG"

# usunięcie kopii starszych niż 14 dni
find "$CEL" -name "www_*.tar.gz" -mtime +14 -delete

echo "Kopia wykonana: $DATA"
```

{% endcode %}

```bash
chmod +x backup.sh
./backup.sh
```

<table data-search="false"><thead><tr><th>Element</th><th>Znaczenie</th></tr></thead><tbody><tr><td><code>#!/bin/bash</code></td><td>Wskazuje, jakim interpreterem uruchomić skrypt</td></tr><tr><td><code>set -euo pipefail</code></td><td>Przerywa skrypt przy błędzie, braku zmiennej lub błędzie w potoku</td></tr><tr><td><code>ZMIENNA="wartosc"</code></td><td>Przypisanie zmiennej (bez spacji wokół <code>=</code>)</td></tr><tr><td><code>$(polecenie)</code></td><td>Podstawienie wyniku polecenia</td></tr><tr><td><code>"$ZMIENNA"</code></td><td>Użycie zmiennej (zawsze w cudzysłowie)</td></tr><tr><td><code>$1</code>, <code>$2</code></td><td>Argumenty przekazane do skryptu</td></tr><tr><td><code>$?</code></td><td>Kod wyjścia ostatniego polecenia (0 = sukces)</td></tr></tbody></table>

Pętla i warunek:

```bash
for plik in *.log; do
    echo "Przetwarzam $plik"
done

if [ -f /etc/nginx/nginx.conf ]; then
    echo "Nginx jest zainstalowany"
fi
```

### Zmienne środowiskowe i aliasy

```bash
env                              # wszystkie zmienne środowiskowe
echo $PATH                       # ścieżki przeszukiwane przy uruchamianiu poleceń
export ZMIENNA="wartosc"         # ustawienie zmiennej do końca sesji
alias ll='ls -lah'               # skrót polecenia do końca sesji
```

Aby aliasy i zmienne były stałe, dopisz je do `~/.bashrc`, a następnie wykonaj `source ~/.bashrc`.

### Dobrze wiedzieć

* Przed każdą destrukcyjną operacją (`rm -r`, `find -delete`, `rsync --delete`, `dd`, `mkfs`) wykonaj ją najpierw w trybie próbnym lub podejrzyj, czego dotyczy.
* `dd` i `mkfs` nadpisują dane na wskazanym urządzeniu bez pytania. Pomyłka w nazwie dysku (`/dev/sda` zamiast `/dev/sdb`) oznacza utratę danych, więc sprawdź ją przez `lsblk`.
* Kopia zapasowa, której nigdy nie próbowałeś odtworzyć, to nie jest pewna kopia. Okresowo testuj odtwarzanie.
* Trzymaj kopie poza serwerem, na którym działa usługa. Kopia na tym samym dysku nie chroni przed awarią dysku.
* Przy zmianach w SSH, zaporze i `/etc/fstab` zawsze zostaw otwartą drugą sesję i przetestuj zmianę, zanim zamkniesz pierwszą.
* `kill -9` (SIGKILL) nie daje procesowi szansy na zapisanie danych. Najpierw użyj zwykłego `kill`, a `-9` zostaw na ostateczność.
* Gdy dysk jest „pełny” mimo wolnego miejsca w `df -h`, sprawdź `df -i` (brak i-węzłów) oraz `lsof | grep deleted` (usunięte pliki wciąż trzymane przez procesy).
* Gdy proces nagle znika, sprawdź `dmesg -T | grep -i "out of memory"`. Jądro mogło go zatrzymać z powodu braku RAM-u (OOM killer).
* Polecenia wpisane przez `sudo` zapisują się w `/var/log/auth.log`, a historia powłoki w `~/.bash_history`. Nie wpisuj haseł jako argumentów poleceń, bo zostaną w historii.
* Zamiast edytować `/etc/sudoers` zwykłym edytorem, używaj `visudo`, który sprawdza składnię przed zapisem.
* Zmiany w `/etc/crontab` i `/etc/cron.d/` mają dodatkową kolumnę z nazwą użytkownika, w odróżnieniu od `crontab -e`.
* Jeśli polecenie działa ręcznie, a w cronie nie, najczęściej winne są względne ścieżki i brakujące zmienne środowiskowe.
* Wiele poleceń ma tryb próbny lub podglądu (`rsync -n`, `apt -s`, `sshd -t`, `nginx -t`). Warto z niego korzystać przed zastosowaniem zmian.
* Po aktualizacji jądra lub bibliotek systemowych często potrzebny jest restart (`reboot`). Informację o tym zobaczysz w pliku `/var/run/reboot-required` na Ubuntu.
