Przejdź do treści
Lekcja 106 z 117

Kurs › Moduł 12 › Lekcja 106

Pytania rekrutacyjne: pliki i uprawnienia

⏱ ok. 16 min czytania· moduł 12: Rozmowa rekrutacyjna

Po tej lekcji: kursant odpowiada na głos, w 30–60 sekund i bez lania wody, na dwanaście pytań o pliki, linki, i-węzły, uprawnienia i narzędzia tekstowe, które najczęściej padają na rozmowie na juniora admina.

Wstęp

„Proszę mi powiedzieć, czym się różni link twardy od symbolicznego.”

I nagle w głowie pustka. Wiesz to. Robiłeś to w lekcji o linkach. Ale teraz ktoś patrzy, kamera w laptopie świeci, a mózg robi niebieski ekran.

Przez najbliższe cztery lekcje trenujemy dokładnie ten moment. Pytania wziąłem z kilku popularnych zestawień pytań rekrutacyjnych na admina Linuksa (KodeKloud, TestGorilla, HiPeople, Hyring i repozytorium „test-your-sysadmin-skills” na GitHubie) i wybrałem te, które powtarzają się w kilku z nich. Do każdego dostajesz odpowiedź do powiedzenia na głos, krótki pokaz w terminalu, to, czego rekruter naprawdę szuka, i odpowiedź, po której rekruter coś notuje. I to nie jest „świetny kandydat”.

Zasady gry: jak odpowiadać

Każda dobra odpowiedź ma cztery kroki, jak przepis:

  1. Jedno zdanie definicji. Bez wstępu „no to tak, generalnie…”.
  2. Obraz albo przykład. Pokazujesz, że rozumiesz, a nie recytujesz.
  3. Komenda. Jak to sprawdzić na serwerze.
  4. Kiedy to ma znaczenie w pracy. To jest moment, w którym junior brzmi jak ktoś, kto już coś naprawiał.

Trzydzieści do sześćdziesięciu sekund. Dłużej i rekruter zaczyna patrzeć na zegarek. Krócej i myśli, że wykułeś jedno zdanie z Wikipedii.

Odpowiedź na głos: Link twardy to druga nazwa dla tego samego pliku. Obie nazwy wskazują ten sam i-węzeł, więc to ten sam plik, tylko z dwiema tabliczkami na drzwiach. Usunę jedną nazwę, dane zostają, dopóki istnieje choć jedna. Link symboliczny to osobny malutki plik, w którym zapisana jest ścieżka do celu, coś jak skrót na pulpicie. Jak usunę cel, link zostaje, ale prowadzi donikąd. Twardego linku nie zrobię do folderu ani na inny system plików, symboliczny może wskazywać cokolwiek, także folder na innym dysku.

echo "tajny przepis" > oryginal.txt
ln oryginal.txt twardy.txt
ln -s oryginal.txt miekki.txt
ls -li oryginal.txt twardy.txt miekki.txt
rm oryginal.txt
cat twardy.txt
cat miekki.txt
1084006 lrwxrwxrwx 1 root root 12 Nov  3 22:33 miekki.txt -> oryginal.txt
1084005 -rw-r--r-- 2 root root 14 Nov  3 22:33 oryginal.txt
1084005 -rw-r--r-- 2 root root 14 Nov  3 22:33 twardy.txt
tajny przepis
cat: miekki.txt: No such file or directory

Pierwsza kolumna to numer i-węzła. oryginal.txt i twardy.txt mają ten sam, a licznik linków to 2. Po usunięciu oryginału twardy link dalej czyta przepis, a symboliczny świeci na czerwono.

Czego rekruter naprawdę szuka: słowa „i-węzeł” i ograniczeń: nie na folder, nie między systemami plików.

ln: katalog: hard link not allowed for directory
ln: failed to create hard link 'tutaj' => '/proc/version': Invalid cross-device link

Zła odpowiedź: „Twardy jest mocniejszy, a symboliczny jest symboliczny.” Brzmi jak horoskop.

Pytanie 2: „Co to jest i-węzeł i co w nim jest?”

Odpowiedź na głos: I-węzeł, po angielsku inode, to karta katalogowa pliku. Każdy plik na systemie plików typu ext4 czy XFS ma jedną. Jest w niej typ pliku, uprawnienia, właściciel i grupa, rozmiar, znaczniki czasu, liczba twardych linków i informacja, w których blokach na dysku leżą dane. Czego w niej nie ma? Nazwy pliku. Nazwa siedzi w folderze, a folder to po prostu lista par „nazwa, numer i-węzła”. Dlatego zmiana nazwy w obrębie jednego dysku jest natychmiastowa, nawet dla pliku 50 GB: zmienia się tylko wpis w spisie.

stat twardy.txt
  File: twardy.txt
  Size: 14        	Blocks: 8          IO Block: 4096   regular file
Device: 254,0	Inode: 1084005     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Modify: 2026-11-03 22:33:05.031896577 +0100

Links: 1, bo oryginał już usunęliśmy. Plik żyje, dopóki licznik nie spadnie do zera i nikt go nie trzyma otwartego. To drugie zdanie zapamiętaj, wróci w lekcji 107 przy df kontra du.

Czego rekruter naprawdę szuka: „nazwa nie jest w i-węźle”. To oddziela ludzi, którzy rozumieją, od tych, którzy przeczytali definicję.

Zła odpowiedź: „To taki identyfikator pliku.” Prawda, ale to jak powiedzieć, że PESEL to „taki numer”.

Pytanie 3: „Dysk ma wolne miejsce, a system mówi No space left on device. Co się dzieje?”

Odpowiedź na głos: Najpewniej skończyły się i-węzły. Na ext4 ich liczba jest ustalana przy zakładaniu systemu plików. Jeśli program nasypał milionów malutkich plików, na przykład sesji, plików w kolejce poczty czy cache, to kart katalogowych zabraknie wcześniej niż miejsca. Sprawdzam df -i, szukam folderu z największą liczbą plików przez du --inodes i sprzątam. Na przyszłość: rotacja albo osobny system plików z większą liczbą i-węzłów.

Pokaz na małym, specjalnie zrobionym systemie plików z 64 i-węzłami (plik obrazu podpięty jako dysk, więc nic nie ryzykujesz):

truncate -s 20M ino.img
mkfs.ext4 -q -N 64 ino.img
sudo mount -o loop ino.img mnt
for i in $(seq 1 100); do touch mnt/p$i || break; done
df -h mnt
df -i mnt
touch: cannot touch 'mnt/p54': No space left on device
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop1       16M   24K   15M   1% /home/eryk/mnt
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/loop1         64    64     0  100% /home/eryk/mnt

Miejsca: jeden procent zajęty. I-węzłów: sto procent. Parking pusty, ale przy szlabanie skończyły się bilety.

sudo du --inodes -x -d1 / 2>/dev/null | sort -rn | head

Czego rekruter naprawdę szuka: df -i. Jedna flaga, a w CV wygląda jak trzy lata doświadczenia.

Zła odpowiedź: „Trzeba dokupić większy dysk.” Większy dysk z tą samą liczbą małych plików zapcha się tak samo, tylko później i bardziej boleśnie.

Pytanie 4: „Gdzie w Linuksie szukasz konfiguracji, logów, programów i danych?”

Odpowiedź na głos: Układ folderów opisuje standard FHS, więc jest prawie taki sam na każdej dystrybucji. Konfiguracja w /etc, logi w /var/log, dane programów, na przykład baz, w /var/lib, programy w /usr/bin i /usr/sbin, rzeczy instalowane ręcznie w /usr/local albo /opt, jądro w /boot, a /proc i /sys to wirtualne okna do jądra, których nie ma na dysku. /tmp może być czyszczony przy restarcie, więc nic ważnego tam nie trzymam.

cat /etc/os-release
ls /var/log

Czego rekruter naprawdę szuka: że nie zgubisz się na obcym serwerze. Bonus, jeśli powiesz, że [Ubuntu] log logowań to /var/log/auth.log, a [RHEL] /var/log/secure, i że na obu journalctl jest pod ręką.

Zła odpowiedź: „Wszystko jest w Program Files.” Rekruter się zaśmieje, ale to nie będzie śmiech sympatii.

Pytanie 5: „Co znaczy chmod 750? A 644?”

Odpowiedź na głos: Trzy cyfry to trzy grupy: właściciel, grupa, reszta świata. Każda cyfra to suma: odczyt to 4, zapis 2, wykonanie 1. Siedem, czyli 4+2+1, to wszystko. Pięć, czyli 4+1, to odczyt i wykonanie. Zero to nic. Więc 750: właściciel robi wszystko, grupa może czytać i uruchamiać, reszta nie ma wstępu. Typowe dla skryptu albo folderu zespołu. 644 to typowy plik: właściciel czyta i pisze, wszyscy inni tylko czytają.

chmod 750 raport.sh
ls -l raport.sh
stat -c '%a %A %n' raport.sh
-rwxr-x--- 1 root root 0 Nov  3 22:33 raport.sh
750 -rwxr-x--- raport.sh

Czego rekruter naprawdę szuka: że umiesz to przeliczyć w głowie w obie strony. Często dopyta: „a co znaczy x na folderze?”. Odpowiedź: prawo wejścia do środka. Bez x na folderze nie otworzysz pliku w środku, nawet jeśli sam plik ma 777.

Zła odpowiedź: „chmod 777 i działa.” Działa. Tak jak drzwi bez zamka.

Pytanie 6: „Jesteś właścicielem pliku, a nie możesz do niego pisać. Dlaczego?”

Odpowiedź na głos: Kilku podejrzanych, sprawdzam po kolei. Raz: uprawnienia właściciela nie mają w, na przykład plik ma 444. Dwa: system plików jest zamontowany tylko do odczytu, często po błędzie dysku. Trzy: plik ma atrybut „niezmienny” ustawiony przez chattr +i, wtedy nawet root nie zapisze. Cztery: ACL albo SELinux czy AppArmor blokują dostęp mimo zwykłych uprawnień. Pięć: dysk albo i-węzły pełne. Komunikat błędu podpowiada, którą ścieżką iść.

sudo chattr +i plik.txt
echo test > plik.txt
lsattr plik.txt
sudo mount -o remount,ro mnt && touch mnt/x
bash: line 1: plik.txt: Operation not permitted
----i---------e------- plik.txt
touch: cannot touch 'mnt/x': Read-only file system

Zwróć uwagę na trzy różne komunikaty: „Permission denied” to uprawnienia, „Operation not permitted” przy roocie to często atrybut i, „Read-only file system” mówi sam za siebie.

Czego rekruter naprawdę szuka: że wymienisz więcej niż jedną przyczynę i że czytasz komunikat błędu, zamiast zgadywać.

Zła odpowiedź: „To się da przez sudo.” Na atrybut i i system tylko do odczytu sudo nie pomoże, a w tym drugim przypadku właśnie przegapiłeś awarię dysku.

Pytanie 7: „Wyjaśnij SUID, SGID i sticky bit”

Odpowiedź na głos: To trzy specjalne bity uprawnień. SUID na programie znaczy: uruchom go z prawami właściciela pliku, a nie osoby, która go odpala. Klasyk to passwd: zwykły użytkownik zmienia hasło, a program musi zapisać /etc/shadow, do którego dostęp ma tylko root. SGID na programie daje prawa grupy pliku, a na folderze sprawia, że nowe pliki dziedziczą grupę folderu, co jest świetne dla folderów zespołu. Sticky bit na folderze oznacza: każdy może tu tworzyć pliki, ale usunąć może tylko swoje. Tak działa /tmp.

ls -l /usr/bin/passwd /usr/bin/crontab
ls -ld /tmp
-rwsr-xr-x 1 root root    64152 May 30  2024 /usr/bin/passwd
-rwxr-sr-x 1 root crontab 39664 Mar 31  2024 /usr/bin/crontab
drwxrwxrwt 20 root root 12288 Nov  3 22:33 /tmp

s w miejscu x właściciela to SUID, s w grupie to SGID, t na końcu to sticky. Liczbowo to czwarta cyfra z przodu: 4 dla SUID, 2 dla SGID, 1 dla sticky. Folder zespołu z SGID:

sudo chmod 2775 /srv/projekt
touch /srv/projekt/plan.txt
ls -l /srv/projekt/plan.txt

A sticky w akcji: użytkownik nobody próbuje skasować plik roota z folderu z prawami 1777, mimo że sam plik ma 666:

rm: cannot remove '/tmp/wspolny/root.txt': Operation not permitted

Dopisać do niego może, bo plik ma 666. Ale skasować nie, bo to nie jego plik. Bez sticky bitu ten sam rm przechodzi bez słowa.

Czego rekruter naprawdę szuka: że wiesz, czemu SUID to temat bezpieczeństwa. Program z SUID roota i dziurą to darmowy root dla atakującego. Dlatego admin zna komendę:

sudo find / -xdev -perm -4000 -type f 2>/dev/null

Zła odpowiedź: „Sticky bit sprawia, że plik się przykleja.” Do czego? Do CV jako ostrzeżenie.

Pytanie 8: „Czy możesz usunąć plik, do którego nie masz prawa zapisu?”

To pytanie z haczykiem i lubię je, bo pokazuje, kto naprawdę rozumie uprawnienia.

Odpowiedź na głos: Tak, jeśli mam prawo zapisu do folderu. Usunięcie pliku to wykreślenie jego nazwy ze spisu w folderze, więc liczą się uprawnienia folderu, a nie pliku. Plik może mieć 444, a i tak zniknie. Odwrotnie też: pliku 666 w cudzym folderze 755 usunąć się nie da. Wyjątek to sticky bit, który mówi „w tym folderze kasujesz tylko swoje”.

rm: cannot remove '/tmp/wspolny/f/a': Permission denied   ← plik 666, folder 755
rm pliku 444 w folderze 777: 0                                  ← poszło

Czego rekruter naprawdę szuka: zdania „usunięcie to zmiana folderu, nie pliku”. Ono łączy się z pytaniem 2 o i-węzły i rekruter to zauważy.

Zła odpowiedź: „Nie, bo plik ma tylko odczyt.” Kandydat właśnie zgubił plik, który był „chroniony”.

Pytanie 9: „Co to jest umask?”

Odpowiedź na głos: umask to maska, która mówi, jakich uprawnień nowy plik albo folder nie dostanie. Programy zwykle tworzą pliki z 666, a foldery z 777, i od tego jądro odejmuje bity z maski. Przy typowym umask 022 pliki wychodzą 644, a foldery 755. Przy 027 grupa nie pisze, a reszta świata nic nie widzi: pliki 640, foldery 750. Ustawiam ją w plikach startowych powłoki albo dla usługi w systemd przez UMask=.

umask
umask 027
touch u1; mkdir u2
ls -ld u1 u2
umask -S
022
-rw-r----- 1 root root    0 Nov  3 22:33 u1
drwxr-x--- 2 root root 4096 Nov  3 22:33 u2
u=rwx,g=rx,o=

Czego rekruter naprawdę szuka: słowa „odejmuje” i tego, że umask nigdy nie doda prawa wykonania plikowi. Dlatego skrypt po zapisaniu zawsze potrzebuje chmod +x.

Zła odpowiedź: „umask to uprawnienia domyślne.” Odwrotnie. To jak powiedzieć, że lista rzeczy zakazanych w samolocie to lista bagażu.

Pytanie 10: „Jak znajdziesz pliki większe niż 100 MB albo zmienione w ostatniej godzinie?”

Odpowiedź na głos: find. Podaję, gdzie szukać, potem warunki. -size +100M to większe niż sto megabajtów, -mmin -60 to zmienione w ostatnich sześćdziesięciu minutach, -mtime +30 to starsze niż trzydzieści dni. -xdev nie wychodzi poza jeden system plików, żeby nie przeszukiwać /proc czy dysków sieciowych. Najpierw zawsze listuję, a dopiero potem dokładam -delete albo -exec.

sudo find / -xdev -type f -size +100M -exec ls -lh {} + 2>/dev/null
sudo find /etc -type f -mmin -60
find ~ -name '*.tmp' -mtime +30 -print

Czego rekruter naprawdę szuka: -xdev, 2>/dev/null i nawyku „najpierw -print, potem -delete”.

Zła odpowiedź: „Otworzyłbym menedżer plików i posortował po rozmiarze.” Na serwerze bez ekranu. Powodzenia.

Pytanie 11: „Czym się różnią grep, sed i awk?”

Odpowiedź na głos: Wszystkie trzy czytają tekst linijka po linijce, ale mają inne zawody. grep szuka: przepuszcza linijki, które pasują do wzorca. sed edytuje: zamienia, usuwa, wstawia, najczęściej s/stare/nowe/, także w pliku przez -i. awk widzi kolumny i liczy: wypisz pierwszą kolumnę, zsumuj dziesiątą, pokaż linijki, gdzie kod odpowiedzi jest większy niż 499. Często łączę je rurą.

Log serwera WWW do pokazu, sześć linijek:

grep ' 500 ' access.log
sed -i.bak 's/^PermitRootLogin yes/PermitRootLogin no/' sshd_test.conf
awk '$9 >= 500 {print $1, $7}' access.log
awk '{print $1}' access.log | sort | uniq -c | sort -rn
awk '{s += $10} END {print s " bajtów"}' access.log
10.0.0.5 - - [03/Nov/2026:08:02:01 +0100] "GET /koszyk HTTP/1.1" 500 64
10.0.0.5 - - [03/Nov/2026:08:03:44 +0100] "GET /koszyk HTTP/1.1" 500 64
10.0.0.5 /koszyk
10.0.0.5 /koszyk
      3 10.0.0.5
      2 10.0.0.7
      1 192.168.1.20
1152 bajtów

Ranking adresów IP to ulubione zadanie rekruterów na żywo. Masz go w jednej linijce.

Czego rekruter naprawdę szuka: jednego zdania na narzędzie i przykładu z życia: log, konfiguracja, ranking. sed -i.bak, czyli edycja z kopią zapasową, to dodatkowy punkt.

Zła odpowiedź: „Do wszystkiego używam Pythona.” Super. A teraz serwer, na którym Pythona nie ma, i pięć minut.

Pytanie 12: „Co robią >, >> i 2>&1? Czy kolejność ma znaczenie?”

Odpowiedź na głos: Dwa głośniki. > przekierowuje normalne wyjście, czyli głośnik 1, do pliku i nadpisuje go. >> dopisuje na końcu. 2> przekierowuje błędy, głośnik 2. 2>&1 znaczy: wyślij błędy tam, gdzie właśnie teraz idzie wyjście. I tak, kolejność ma znaczenie, bo Bash czyta przekierowania od lewej. > plik 2>&1 wysyła oba do pliku. 2>&1 > plik wysyła błędy na ekran, bo w chwili kopiowania głośnik 1 był jeszcze ekranem.

ls access.log brak.txt > wynik1.txt 2>&1
ls access.log brak.txt 2>&1 > wynik2.txt
cat wynik1.txt; echo ---; cat wynik2.txt
ls: cannot access 'brak.txt': No such file or directory      ← z drugiej komendy, prosto na ekran
ls: cannot access 'brak.txt': No such file or directory
access.log
---
access.log

Czego rekruter naprawdę szuka: wyjaśnienia kolejności. Każdy umie powiedzieć „2>&1 łączy błędy z wyjściem”, mało kto wie, czemu odwrotna kolejność nie działa.

Zła odpowiedź: „>> to mocniejsze >.” Nie. To łagodniejsze. Nie niszczy tego, co było.

Jak to działa pod spodem

Prawie wszystkie dzisiejsze pytania sprowadzają się do jednego obrazu. Dysk to archiwum. Każdy plik ma kartę katalogową, czyli i-węzeł, z uprawnieniami, właścicielem i adresem półek z danymi. Folder to zwykły plik, w którym leży spis „nazwa → numer karty”.

  • Link twardy to dopisanie drugiej nazwy do spisu z tym samym numerem karty.
  • Usunięcie pliku to wykreślenie nazwy ze spisu, więc decydują prawa do spisu, czyli folderu.
  • Dane znikają naprawdę dopiero, gdy licznik nazw spadnie do zera i żaden proces nie trzyma pliku otwartego.
  • Kart jest skończona liczba, dlatego można zapełnić dysk, nie zapełniając go.

Przy każdym otwarciu pliku jądro sprawdza po kolei: czy proces jest właścicielem, a jeśli nie, czy należy do grupy pliku, a jeśli nie, bierze bity „reszty świata”. Bierze tylko pierwszy pasujący zestaw. Ciekawostka na rozmowę: jeśli plik ma 604, a Ty jesteś w jego grupie, nie przeczytasz go, choć „reszta świata” może. Sprawdziłem:

-rw----r-- 1 root nogroup 7 Nov  3 22:36 604.txt
cat: 604.txt: Permission denied     ← nobody w grupie nogroup
sekret                              ← nobody spoza grupy

Jądro dopasowało Cię do grupy i dalej nie patrzy. Dopiero potem swoje zdanie mają ACL i SELinux albo AppArmor.

Ściąga flag

KomendaFlagaCo robi
ls-ipokazuje numer i-węzła
ls-ldpokazuje sam folder, nie jego zawartość
ln-stworzy link symboliczny (bez flagi: twardy)
stat-c '%a %A'uprawnienia liczbowo i literami
df-izajętość i-węzłów zamiast miejsca
du--inodesliczy pliki zamiast bajtów
chmod4755 / 2775 / 1777SUID / SGID / sticky plus zwykłe prawa
chattr+i / -iwłącza/wyłącza „niezmienny”
lsattr—pokazuje atrybuty pliku
umask-Smaska literami
find-perm -4000pliki z SUID
find-size +100M / -mmin -60 / -mtime +30rozmiar / minuty / dni
find-xdevnie wychodzi poza ten system plików
grep-r / -i / -vrekurencyjnie / bez wielkości liter / odwrotnie
sed-i.bakedycja w miejscu z kopią zapasową
awk-F:separator kolumn

⚠ Typowy błąd

Na rozmowie najczęstszy błąd to nie zła odpowiedź, tylko odpowiedź na inne pytanie. Rekruter pyta „czym się różni link twardy od symbolicznego”, a kandydat przez dwie minuty opowiada, jak się robi link symboliczny.

Dlaczego tak się dzieje? Bo stres każe mówić cokolwiek, co się zna. Naprawa: powtórz pytanie w pierwszym zdaniu odpowiedzi. „Różnica między linkiem twardym a symbolicznym jest taka, że…”. Brzmi szkolnie, ale trzyma Cię na torach.

A na koniec błąd techniczny, który wychodzi przy pytaniu o uprawnienia częściej, niż myślisz:

sudo echo "nameserver 1.1.1.1" > /etc/resolv.conf
bash: /etc/resolv.conf: Permission denied

Przekierowanie robi Twój Bash, a nie sudo. Poprawnie: echo "..." | sudo tee /etc/resolv.conf. Jeśli rekruter zapyta, czemu tak, a Ty odpowiesz, masz u niego plusa.

✎ Zadanie

  1. Odpowiedz na głos, z zegarkiem w ręku, na pytania 1, 5 i 7. Każde maksymalnie 60 sekund.
  2. Na swojej maszynie wirtualnej zrób plik, link twardy i link symboliczny do niego, pokaż ls -li, usuń oryginał i sprawdź, który link dalej działa.
  3. Znajdź wszystkie programy z bitem SUID na swoim systemie i policz je jedną linijką z rurą.
Pokaż rozwiązanie

Punkt pierwszy, odpowiedzi na głos, zostaje między Tobą a zegarkiem. Jeśli przy linku twardym powiedziałeś „i-węzeł” w pierwszych dwudziestu sekundach, jest dobrze.

Punkt drugi robiliśmy w lekcji: ls -li pokazuje ten sam numer i-węzła przy oryginale i linku twardym, a po rm oryginal.txt działa tylko twardy.

Punkt trzeci:

sudo find / -xdev -perm -4000 -type f 2>/dev/null | wc -l
find /usr -perm -4000 -type f | wc -l
20

U mnie w /usr jest dwadzieścia programów z SUID: passwd, sudo, su, mount i spółka. Jeśli na całym / wyjdzie Ci dużo więcej, zobacz, gdzie leżą: | cut -d/ -f2-3 | sort | uniq -c. Program z SUID w czyimś folderze domowym albo w /tmp to nie ciekawostka, to zgłoszenie do działu bezpieczeństwa.

Co dalej

Pliki mamy. W następnej lekcji pytania o to, co się na tych plikach uruchamia: zombie i sieroty, kill -15 kontra kill -9, load average, OOM killer, start systemu, swap, fstab, LVM i zagadka, czemu df i du się kłócą.