Cvičení: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.
Poslední aktuality jsou v issue #112 (z 15. dubna).
Na tomto cvičení probereme několik témat, která nejsou příliš rozsáhlá. Navíc spolu souvisí jen částečně, takže si můžete velké části přečíst v prakticky libovolném pořadí, které vám vyhovuje.
Tohle je asi nejteoretičtější cvičení: není tu moc věcí k přímému procvičení ale zato poměrně dost informací, které snad zlepší propojení dřívějších částí.
Tohle cvičení také obsahuje malý domácí úkol za dva body.
Předstartovní kontrola
- Pamatujete si, k čemu se používají shellové wildcardy (zástupné znaky).
- Víte, že řetězce v C jsou zakončeny nulovým bajtem.
Unixová přístupová práva
Zatím jsme spíše ignorovali fakt, že je na každém Linuxovém systému více uživatelských účtů. A také to, že uživatelé nemůžou přistupovat ke všem souborům. V této části vysvětlíme základy Unixových přístupových práv, a jak je interpretovat.
Konec konců se můžete přihlásit ke sdílenému počítači a měli byste být schopni pochopit, k čemu máte přístup a k čemu ne.
Vzpomeňme si, co jsme říkali o /etc/passwd
– obsahuje seznam
uživatelských účtů na tom konkrétním stroji (technicky to není jediný možný
zdroj uživatelských záznamů, ale prozatím je to dobrá aproximace).
Každá běžící aplikace, tedy process, je vlastněná jedním z uživatelů z
/etc/passwd
(opět to tu trochu zjednodušujeme). Také říkáme, že tento
proces běží pod konkrétním uživatelem.
A každý soubor v souborovém systému (včetně jak reálných souborů jako
~/.bashrc
, tak virtuálních jako /dev/sda
nebo /proc/uptime
) má svého
vlastníka.
Když se proces pokouší číst nebo upravovat soubor, operační systém rozhodne, jestli je tato operace oprávněná. Toto rozhodnutí je založené na vlastníkovi souboru, vlastníkovi procesu a právech definovaných pro daný soubor. Je-li operace zakázána, vstupní/výstupní funkce ve vašem programu vyvolá výjimku (např. v Pythonu) nebo vrátí chybový kód (v C).
Protože model založený pouze na vlastnících by nebyl dostatečně flexibilní,
máme také skupiny uživatelů (definované v /etc/group
). Každý uživatel je
členem jedné nebo více skupin, z nichž jedné se říká primární
skupina. Tyto skupiny jsou asociované s každým procesem daného
uživatele. Soubory pak mají jak vlastnícího uživatele, tak vlastnící
skupinu.
Soubory mají přiřazené tři množiny oprávnění: jednu pro vlastníka souboru, druhou pro uživatele ve vlastnící skupině a třetí pro všechny ostatní uživatele. Přesný algoritmus pro určení, která množina bude použita, vypadá takto:
- Je-li uživatel, který proces spustil, stejný jako vlastník souboru, jsou použita přístupová práva vlastníka (někdy také označované jako uživatelská přístupová práva).
- Je-li uživatel běžícího procesu ve skupině, která byla nastavena u souboru, jsou použita skupinová (group) přístupová práva.
- Jinak systém použije ostatní přístupová práva.
Každá množina oprávnění obsahuje tři práva: čtení (r
), zápis (w
),
spouštění (execute, x
):
-
Operace čtení a zápisu souboru se chovají očekávatelně.
-
Právo na spouštění se ověřuje v případě, kdy se uživatel snaží spustit soubor jako program (připomeňme, že bez
chmod +x
, se v takovém případě objevovala chyba Permission denied: zde je její důvod).- Poznamenejme, že skript, který lze číst, ale není spustitelný, můžeme stále spustit zavoláním příslušného interpretru manuálně.
- Po spuštění programu nový proces zdědí vlastníka a skupiny svého rodiče
(např. shellu, který jej spustil). Vlastnictví samotného spustitelného
souboru není směrodatné po jeho spuštění. Například
/usr/bin/mc
vlastní uživatelroot
, ale přesto může být spuštěn libovolným uživatelem a běžící proces je poté vlastněný tím, kdo jej spustil.
Stejná oprávnění se vztahují také na adresáře, ale jejich význam je trochu odlišný:
- Právo na čtení umožňuje uživateli číst seznam souborů uvnitř (běžných, symlinků, podadresářů, atd.).
- Právo na zápis uživateli umožňuje vytvářet, odstraňovat a přejmenovávat soubory uvnitř. Všimněte si, že odstranění práva na zápis k souboru uvnitř zapisovatelného adresáře, je bezvýznamné, protože to uživateli nezabrání v tom, aby soubor nahradil úplně novým.
- Spustitelné (executable) právo na adresáři umožňuje uživateli otevírat
položky uvnitř. (Má-li adresář
x
, ale ner
, můžeme používat soubory uvnitř, pokud známe jejich názvy, nemůžeme ale vypsat jejich seznam. Na druhou stranu, má-li adresářr
, ale nex
, můžeme vypsat seznam souborů, ale nemůžeme je použít.)
Oprávnění souboru nebo adresáře může měnit pouze jejich vlastník a to bez ohledu na aktuální oprávnění. To znamená, že vlastník může sám sobě odepřít přístup odstraněním všech přístupových práv, ale stejně jej poté může později obnovit.
Uživatelský účet root
Vedle účtů pro normální uživatele je zde vždy i účet pro takzvaného superuživatele – obvykle nazývaného jen root – ten má administrátorská práva a je tedy oprávněn dělat cokoliv s libovolným souborem v systému. Ověřování oprávnění popsané výše jednoduše vůbec neplatí pro procesy vlastněné rootem.
Zobrazování a změna oprávnění
Podíváme-li se na zkratky rwx
pro jednotlivá oprávnění, možná vám budou
povědomá:
drwxr-xr-x 1 intro intro 48 Feb 23 16:00 02/
drwxr-xr-x 1 intro intro 60 Feb 23 16:00 03/
-rw-r--r-- 1 intro intro 51 Feb 23 16:00 README.md
První sloupec obsahuje typ položky (d
pro adresář, -
pro obyčejný
soubor, atd.) a tři trojice oprávnění. První trojice se vztahuje k
vlastníkovi souboru, prostřední ke skupině a poslední ke zbytku světa (k
ostatním). Třetí a čtvrtý sloupec obsahují vlastníka a skupinu souboru.
Vaše osobní soubory v domovském adresáři budou typicky mít za vlastníka vás spolu se skupinou stejného jména. Jde o výchozí konfiguraci, která brání ostatním uživatelům, aby viděli vaše soubory.
Zkontrolujte, zda toto platí pro všechny adresáře pod /home
na sdíleném
počítači.
Poznamenejme, že většina souborů je ve skutečnosti přístupná ke čtení všem.
To je v pořádku, protože když se podíváte na oprávnění pro svůj ~
,
uvidíte, že je to typicky drwx------
. Jen vlastník jej může upravovat a
provést cd
dovnitř. Vzhledem k tomu, že nikdo nemůže změnit svůj pracovní
adresář na vaši domovskou složku, nikdo nemůže ani číst vaše soubory
(technicky, čtení souboru znamená projít celou adresářovou strukturu a
ověřit přístupová práva na celé této cestě).
Na změnu oprávnění můžete použít program chmod
. Ten má obecně formát
chmod WHO[+=-]PERMISSION file1 file2 ...
WHO
může být prázdné (pro všechny – uživatele, skupinu a ostatní) nebo
určení u
, g
nebo o
. A PERMISSION
může být r
, w
nebo x
.
Je možné je kombinovat, takže např. g-r,u=rw
odstraní právo na čtení
souboru pro skupinu a nastaví oprávnění čtení i zápisu pro vlastníka (čili
soubor nebude spustitelný bez ohledu na předchozí stav executable bitu).
Kontrola přístupových práv
Vraťme se ještě na chvíli k přístupovým právům.
Změňte oprávnění některých skriptů na --x
.
Zkuste je spustit.
Co se stane?Odpověď.
Odstraňte zapisovatelný bit pro soubor a zapište do něj pomocí přesměrování standardního výstup. Co se stane?
Kvíz o přístupových právech
Za předpokladu následujícího výstupu ls -l
(script.sh
je skutečně skript
shellu) a za předpokladu, že uživatel bob
je ve skupině wonderland
,
zatímco uživatel lewis
nikoli.
-rwxr-xr-- 1 alice wonderland 1234 Feb 20 11:11 script.sh
Vyberte všechna pravdivá tvrzení.
You need to have enabled JavaScript for the quiz to work.Procesy (a signály)
Soubory v systému jsou jeho pasivními prvky. Aktivními částmi jsou spuštěné programy, které data skutečně mění. Podívejme se, co vlastně běží na našem počítači.
Když spustíte program (tj. spustitelný soubor), stane se procesem. Spustitelný soubor a běžící proces sdílí kód – ten je stejný v obou. Ale proces také obsahuje zásobník (stack) (např. pro lokální proměnné), haldu (heap), seznam otevřených souborů apod. – tomu všemu se obvykle říká kontext procesu. Obvykle jsou slovní spojení běžící program a proces zaměňována.
Pro zobrazení seznamu běžících procesů na našem počítači můžeme použít
htop, který zobrazí informace o procesech. Podobně
jako v MidnightCommanderu provádějí nejdůležitější akce funkční klávesy a
nápověda je viditelná v dolní liště. Můžete také nakonfigurovat htop
tak,
aby zobrazoval informace o systému, jako je množství volné paměti nebo
využití procesoru.
Pro neinteraktivní použití můžeme spustit ps -e
(nebo ps -axufw
pro
podrobnější seznam).
Pro ilustraci uvádíme příklad výstupu ps
(s volbou --forest
pro
zobrazení vztahu rodič/dítě).
Chcete-li však zobrazit i běžící procesy svých kolegů, spusťte na sdíleném
počítači příkaz ps -ef --forest
.
UID PID PPID C STIME TTY TIME CMD
root 2 0 0 Feb22 ? 00:00:00 [kthreadd]
root 3 2 0 Feb22 ? 00:00:00 \_ [rcu_gp]
root 4 2 0 Feb22 ? 00:00:00 \_ [rcu_par_gp]
root 6 2 0 Feb22 ? 00:00:00 \_ [kworker/0:0H-events_highpri]
root 8 2 0 Feb22 ? 00:00:00 \_ [mm_percpu_wq]
root 10 2 0 Feb22 ? 00:00:00 \_ [rcu_tasks_kthre]
root 11 2 0 Feb22 ? 00:00:00 \_ [rcu_tasks_rude_]
root 1 0 0 Feb22 ? 00:00:09 /sbin/init
root 275 1 0 Feb22 ? 00:00:16 /usr/lib/systemd/systemd-journald
root 289 1 0 Feb22 ? 00:00:02 /usr/lib/systemd/systemd-udevd
root 558 1 0 Feb22 ? 00:00:00 /usr/bin/xdm -nodaemon -config /etc/X11/...
root 561 558 10 Feb22 tty2 22:42:35 \_ /usr/lib/Xorg :0 -nolisten tcp -auth /var/lib/xdm/...
root 597 558 0 Feb22 ? 00:00:00 \_ -:0
intro 621 597 0 Feb22 ? 00:00:40 \_ xfce4-session
intro 830 621 0 Feb22 ? 00:05:54 \_ xfce4-panel --display :0.0 --sm-client-id ...
intro 1870 830 4 Feb22 ? 09:32:37 \_ /usr/lib/firefox/firefox
intro 1966 1870 0 Feb22 ? 00:00:01 | \_ /usr/lib/firefox/firefox -contentproc ...
intro 4432 830 0 Feb22 ? 01:14:50 \_ xfce4-terminal
intro 4458 4432 0 Feb22 pts/0 00:00:11 \_ bash
intro 648552 4458 0 09:54 pts/0 00:00:00 | \_ ps -ef --forest
intro 15655 4432 0 Feb22 pts/4 00:00:00 \_ bash
intro 639421 549293 0 Mar02 pts/8 00:02:00 \_ man ps
...
Především má každý proces svoje ID, často označované jen PID (neplést s
tímto).
PID je číslo přiřazené jádrem operačního systému a je používáno nástroji pro
správu procesů.
PID 1 je určeno pro první proces spuštěný v systému (0 je vyhrazená pro
speciální účely – mrkněte na fork(2)
pokud vás zajímají detaily).
Když tento proces skončí, systém se vypne.
Ostatní procesy dostávají (v jednoduchosti) postupně se zvyšující PIDy,
časem jsou PIDy recyklovány.
Vzpomeňte si, že tyto informace jsou obsažené též v adresáři /proc/PID
a
odtamtud je také ps
čte.
Pro zobrazení všech procesů v počítači znovu spusťte ps -ef --forest
.
Vzhledem ke grafickému rozhraní bude seznam pravděpodobně poměrně dlouhý.
Prakticky může mít malý server nabízející webové stránky, kalendář a přístup přes SSH asi 80 procesů, u desktopu s prohlížečem běžícím v Xfce a několika dalšími aplikacemi se počet zvýší na téměř 300 (tohle opravdu hodně závisí na konfiguraci, ale je to rozumný přibližný odhad). Asi 50-60 z nich jsou ve skutečnosti vnitřní vlákna jádra. Jinými slovy, webový/kalendářový server potřebuje asi 20 “skutečných” procesů, desktop jich potřebuje asi 200 :-).
Rychlá kontrola znalostí procesů
Signály
Linuxové systémy používají signály pro asynchronní komunikaci mezi běžícími programy (procesy). Slovo asynchronní znamená, že signál může být odeslán (a doručen) bez ohledu na stav procesu. Toto je v kontrastu s komunikací prostřednictvím (například) standardního vstupu, kde program řídí, kdy bude ze standardního vstupu číst (tím, že zavolá odpovídající IO funkce pro čtení).
Signály nicméně nenabízejí příliš bohatou možnost komunikace: jediná informace (kromě toho, že byl vůbec poslán) je jejich číslo. Čísla signálů jsou definována v kernelu, který také některé signály sám zpracovává. V ostatních případech jsou signály doručené aplikaci, která na ně může reagovat. Pokud aplikace na signál nereaguje, je signál zpracován výchozím způsobem. V některých případech se jedná o ukončení aplikace (což je nejčastější). V ostatních případech jsou signály ignorovány.
Tohle je také vyjádřeno tím, že prográmek, kterým se signály posílají se
jmenuje kill
(protože obvykle proces zabije – ukončí), detaily níže.
Bez dalších parametrů kill
posílá signál 15 (nazvaný též TERM
nebo
SIGTERM
), který aplikaci říká, že má být ukončena. Aplikace se může
rozhodnout, že signál tzv. odchytí, např. zavře otevřené soubory a teprve
pak skončí. Aplikace ale může udělat v podstatě cokoliv a dokonce i signál
ignorovat. Kromě TERM
můžeme též pomocí kill
poslat signál KILL
(číslo
9), který je vždy odchycen kernelem a okamžitě (a násilně) program
ukončí. Aplikace se může pokusit zaregistrovat si zachycení signálu KILL
,
ale jádro operačního systému ho stejně nedoručí.
Většina signálů je poslána procesu v reakci na specifickou
událost. Například signál PIPE
je poslán, pokud proces zkouší zapsat do
roury, jejíž čtecí konec byl uzavřen. (Vzpomeňte si na problém z labu
04.) Ukončení programu
pomocí Ctrl-C
v terminálu ve skutečnosti pošle signál INT
(interrupt,
číslo 2). Pokud vás zajímají i ostatní signály, mrkněte na signal(7)
.
Použití kill
, pkill
a pgrep
Příkaz `pgrep lze použít k vyhledání procesů odpovídajících zadanému názvu.
Otevřete dva další terminály a v jednom spusťte sleep 600
a ve druhém
sleep 800
. Program sleep
jednoduše počká daný počet sekund, než se
ukončí.
Ve třetím terminálu spusťte následující příkazy, abyste pochopili, jak probíhá vyhledávání procesů.
pgrep sleep
pgrep 600
pgrep -f 600
Co jste se dozvěděli? Odpověď.
Když známe PID, můžeme použít nástroj kill
a program skutečně
ukončit. Zkuste spustit kill PID
s PID jednoho ze sleepů a podívejte se,
co se stalo v terminálu, kde sleep
běžel.
Měli byste vidět něco takového:
Terminated (SIGTERM).
Tato zpráva nás informuje, že příkaz byl násilně ukončen.
Podobně můžete použít pkill
k zabíjení procesů podle jména (ale buďte
opatrní, protože s velkou mocí přichází i velká zodpovědnost). Další
podrobnosti naleznete na stránkách manuálu.
Reakce na signály v shellu
Reakce na signály v shellu se provádí pomocí příkazu trap
.
Všimněte si, že typickou akcí pro obsluhu signálů v shellovém skriptu je úklid dočasných souborů.
#!/bin/sh
set -ueo pipefail
on_interrupt() {
echo "Interrupted, terminating ..." >&2
exit 17
}
on_exit() {
echo "Cleaning up..." >&2
rm -f "$my_temp"
}
my_temp="$( mktemp )"
trap on_interrupt INT TERM
trap on_exit EXIT
echo "Running with PID $$"
counter=1
while [ "$counter" -lt 10 ]; do
date "+%Y-%m-%d %H:%M:%S | Waiting for Ctrl-C (loop $counter) ..."
echo "$counter" >"$MY_TEMP"
sleep 1
counter=$(( counter + 1 ))
done
Příkaz trap
obdrží jako první argument příkaz, který se má v reakci na
signál vykonat. Další argumenty obsahují seznam signálů, na které se má
reagovat. Všimněte si, že speciální signál EXIT
znamená normální ukončení
skriptu. Proto nemusíme po ukončení smyčky volat on_exit
.
Pro označení ukončení pomocí obsluhy Ctrl-C použijeme exit 17
(hodnota je
sama o sobě libovolná).
Návratovou hodnotu můžete zkontrolovat pomocí echo $?
po ukončení
příkazu. Speciální proměnná $?
obsahuje výstupní kód posledního příkazu.
Použití -
(pomlčky) místo handleru způsobí, že příslušný handler bude
nastaven jako výchozí.
Všimněte si použití $$
, které vypíše aktuální PID.
Spusťte výše uvedený skript, poznamenejte si jeho PID a v novém terminálu spusťte následující příkaz.
kill THE_PID_PRINTED_BY_THE_ABOVE_SCRIPT
Skript byl ukončen a byla zavolána rutina pro úklid. Srovnejte se situací,
kdy jste příkaz trap
odkomentovali.
Spusťte skript znovu, ale předejte -9
do kill
, abyste určili, že chcete
poslat signál devět (tj. KILL
).
Co se stalo? Odpověď.
Signály jsou sice primitivním mechanismem, který předává binární události bez dalších dat, ale jsou hlavním způsobem řízení procesů v systému Linux.
Pokud potřebujete bohatší komunikační kanál, můžete místo něj použít D-Bus.
Nedostatky v návrhu a realizaci signálu
Signály jsou základním mechanismem pro komunikaci mezi procesy v systémech Unix. Bohužel jejich návrh má několik chyb, které komplikují jejich bezpečné použití.
Nebudeme zabíhat do podrobností, ale měli byste mít na paměti, že manipulace se signály může být složitá v situacích, kdy si nemůžete dovolit ztratit žádný signál nebo kdy signály mohou přicházet rychle jeden za druhým. A při používání signálů ve vícevláknových programech se otevírá celá Pandořina skříňka problémů.
Na druhou stranu pro jednoduché shellové skripty, ve kterých chceme při
násilném ukončení provést úklid, postačí přístup, který jsme si ukázali
výše. Ve skriptu tím ohlídáme situaci, kdy uživatelé stiskli Ctrl-C
,
protože zjistili, že pracují se špatnými daty, nebo něco podobného.
Všimněte si však, že takový skript obsahuje chybu pro případ, kdy uživatelé
stisknou Ctrl-C
velmi brzy během provádění skriptu.
my_temp="$( mktemp )"
# User hits Ctrl-C here
trap on_interrupt INT TERM
trap on_exit EXIT
Dočasný soubor byl již vytvořen, ale obslužná rutina ještě nebyla
zaregistrována, a proto nebude soubor odstraněn. Změna pořadí však
komplikuje obsluhu signálu, protože musíme otestovat, že $MY_TEMP
byl již
inicializován.
Rychlá kontrola znalosti signálů
Soubory a správa uložišť
Než budete pokračovat, připomeňte si, že soubory se nacházejí v souborových systémech, což jsou struktury na skutečných blokových zařízeních (typicky discích).
Práce se souborovými systémy a blokovými zařízeními je nutná při instalaci nového systému, při záchraně dat z poškozeného zařízení nebo při prosté kontrole volného místa.
Běžné soubory a adresáře již znáte. V systému Linux však můžete najít i jiné typy souborů.
Symbolické odkazy
Linux umožní vytvořit symbolický odkaz na jiný soubor. Tento speciální druh souboru nemá žádný obsah a jen odkazuje na další soubor.
Zajímavou vlastností symbolických odkazů je, že jsou transparentní pro
standardní souborové I/O API. Pokud zavoláte Pythoní open
na symbolickém
odkazu, otevřete tím (transparentně) soubor, na který odkazuje. To je
zamýšlené chování.
Účelem symbolických odkazů je umožnit jiný pohled na stejné soubory bez nutnosti cokoliv kopírovat a synchronizovat.
Například uvažujme, že přehrávač videí umí přehrávat jen soubory v adresáři
Videos
.
Ve skutečnosti ale máme soubory jinde, protože jsou na sdíleném disku.
S pomocí symbolického odkazu můžete složku Videos
nasměřovat na skutečné
úložiště a přehrávač nic nepozná.
(Pro pořádek, neznáme žádný přehrávač s podobných chováním, ale existuje
spousta jiných programů, kde podobná magie umožní jejich funkci i v
prostředí, pro které nebyly navrženy.)
Symbolický odkaz je něco jiného než zástupce na ploše apod. Tito zástupci jsou ve skutečnosti normální soubory, kde kromě cílového souboru určíte třeba i ikonu apod. Symbolické odkazy fungují o úroveň níže.
Abyste vytvořili symbolický odkaz stačí spustit ln -s
. Například, spuštění
tohoto příkazu vytvoří symbolický odkaz na /etc/passwd
pojmenovaný
users.txt
. Spuštění cat users.txt
pak otevře users.txt
ačkoliv kernel
jeho obsah přečte z /etc/passwd
.
ln -s /etc/passwd users.txt
Speciální soubory
Kromě toho také existují speciální soubory, které reprezentují fyzická zařízení, nebo soubory, které fungují jako kukátka do stavu systému.
Hlavním důvodem je, že je to tak mnohem jednodušší pro vývojáře. Nepotřebujete speciální programy na práci s diskem, nepotřebujete zvláštní program na zjištění stavu paměti. Prostě jen přečtete obsah dobře známého souboru a máte potřebná data.
Je také mnohem jednodušší takové programy testovat – můžete jim předhodit jiný soubor jen změnou cesty. Což je změna, která by neměla rozbít zbytek programu.
Soubory, které reprezentují stav systému, jsou typicky textové.
Například soubor /proc/meminfo
může vypadat takto:
MemTotal: 7899128 kB
MemFree: 643052 kB
MemAvailable: 1441284 kB
Buffers: 140256 kB
Cached: 1868300 kB
SwapCached: 0 kB
Active: 509472 kB
Inactive: 5342572 kB
Active(anon): 5136 kB
Inactive(anon): 5015996 kB
Active(file): 504336 kB
Inactive(file): 326576 kB
...
Tento soubor není nikde na disku, ale když soubor otevřete, Linux vytvoří jeho obsah za běhu.
Všimněte si, jak je informace strukturována: jde o textový soubor, takže nepotřebujete žádné speciální nástroje na přečtení. Navíc je obsah snadno čitelný pro člověka. Na druhou stranu, struktura souboru je pevně daná: co řádek, to záznam; klíč a hodnota jsou odděleny dvojtečkou. Snadné i pro zpracování programem.
Hierarchie souborových systémů
Nyní si stručně uvedeme některé důležité soubory, které najdete prakticky na každém počítači s Linuxem.
Nebojte se skutečně zobrazit obsah souborů, které zde uvádíme. hexdump -C
je opravdu skvělý nástroj.
/boot
obsahuje zavaděč pro načtení operačního systému.
Po instalaci systému se tímto adresářem budete zabývat jen zřídka.
/dev
je speciální adresář, ve kterém jsou umístěny soubory reprezentující hardwarová zařízení
Pravděpodobně tam uvidíte soubor sda
nebo nvme0
, který reprezentuje váš
pevný (nebo SSD) disk.
Pokud tedy nepracujete pod superuživatelem,
nebudete mít k těmto souborům přístup
ale kdybyste je hexdumpovali
, viděli byste bajty tak, jak jsou
na skutečném pevném disku.
Je důležité si uvědomit, že tyto soubory nejsou fyzickými soubory na disku (to by přece znamenalo mít disk uvnitř disku). Při čtení z nich to jádro rozpozná a vrátí správná data.
Tento adresář obsahuje také několik speciálních, ale velmi užitečných souborů pro vývoj softwaru.
/dev/urandom
vrací náhodné bajty po neomezenou dobu.
Pravděpodobně se interně používá uvnitř vašeho oblíbeného programovacího jazyka
k implementaci jeho funkce random()
.
Zkuste na tomto souboru spustit hexdump
(a připomeňte si, že <Ctrl>-C
program ukončíte, až vás už náhodnost přestane bavit).
/dev/null
je taková soukromá černá díra: zahazuje všechno, co se do ní
zapíše.
/etc/
obsahuje konfiguraci systému.
Většina programů v systémech UNIX se obvykle konfiguruje prostřednictvím textových souborů.
Důvodem je to, že správce se musí naučit pouze jeden nástroj – dobrý
textový editor – pro správu systému.
Výhodou je, že většina konfiguračních souborů má podporu pro komentáře a
je možné komentovat i konfiguraci.
Pro představu, příklad takového konfiguračního souboru si můžete prohlédnout v
/etc/systemd/system.conf
.
Asi nejdůležitějším souborem je /etc/passwd
, který obsahuje seznam
uživatelských účtů. Všimněte si, že se jedná o textový soubor, kde každý
řádek představuje jeden záznam a jednotlivé atributy jsou jednoduše odděleny
dvojtečkou :
. To je velmi jednoduché na čtení, velmi jednoduché na úpravu
a velmi jednoduché na pochopení. Jinými slovy, princip
KISS v praxi.
/home
obsahuje domovské adresáře pro běžné uživatelské účty (tj. účty
pro skutečné – lidské – uživatele).
/lib
a /usr
obsahují dynamické knihovny, aplikace a celosystémové
datové soubory.
/var
je určen pro volatilní data. Pokud byste chtěli na svůj počítač nainstalovat databázi nebo webový server,
byly by jeho soubory uloženy zde.
/tmp
je obecné umístění pro dočasné soubory.
Tento adresář je automaticky vyčištěn při každém restartu, proto jej nepoužívejte pro trvalé uložení souborů.
Mnoho systémů také automaticky odstraňuje soubory, které nebyly změněny v
v posledních několika dnech.
/proc
je virtuální souborový systém, který umožňuje ovládání a čtení
nastavení jádra (operačního systému).
Například soubor /proc/meminfo
obsahuje poměrně podrobné informace o
využití paměti RAM.
Opět platí, že /proc/*
nejsou normální soubory, ale virtuální. Dokud je
nepřečtete, jejich obsah nikde fyzicky neexistuje.
Připojování a přípojné body (mounts, mount-points)
Každý souborový systém (ke kterému chceme přistupovat) je někde přístupný jako adresář (v porovnání například s písmenem jednotky v jiných systémech).
Pokud chceme přistoupit k zařízení /dev/sda3
pod /home
, říkáme, že
/dev/sda3
je připojené do /home
, /home
je potom přípojný bod a
/dev/sda3
se často také nazývá svazek (volume
).
Většina zařízení je připojena automaticky při startu.
To zahrnuje /
(kořen, root) kde je systém, ale také /home
, kde jsou
data uživatelů.
Všimněte si, že /dev
a /proc
(kromě jiných) jsou speciální souborové
systémy připojené do těchto míst.
Takže, soubor /proc/uptime
fyzicky vůbec neexistuje (tj. nenajdete žádný
sektor na disku, který by obsahoval jeho data).
Souborové systémy připojené při startu jsou vyjmenovány v /etc/fstab
.
Málokdy jej budete muset měnit (obzvláště na notebooku) a tento –
instalátorem vytvořený – soubor zůstane často beze změn.
Všimněte si, že obsahuje identifikaci svazku (čili cestu k oddílu –
partition), přípojný bod a další možnosti.
Když připojíte vyjímatelný USB disk, vaše desktopové prostředí ho obvykle
připojí automaticky.
Je možné ho připojit i ručně pomocí programu mount
.
Nicméně, program mount
musí běžet pod uživatelem root
(tohle
vlákno vysvětluje, proč může
připojení disku být bráno jako nebezpečná operace).
Takže si s mount
em můžete hrát jen na svých instalacích, kde máte
oprávnění superuživatele.
Na sdílených strojích to fungovat nebude.
Připojování disků ručně
sudo mkdir /mnt/flash
sudo mount /dev/sdb1 /mnt/flash
Vaše data budou viditelná v adresáři /mnt/flash
.
Chcete-li disk odpojit, spusťte následující příkaz:
sudo umount /mnt/flash
Všimněte si, že spuštění příkazu mount
bez argumentů vypíše seznam
aktuálně připojených disků. K tomu nejsou vyžadována práva roota.
Prográmky pro zjištění zaplněnosti disku
Základním nástrojem pro kontrolu volného místa na disku je df
(disk free).
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 8174828 0 8174828 0% /dev
tmpfs 8193016 0 8193016 0% /dev/shm
tmpfs 3277208 1060 3276148 1% /run
/dev/sda3 494006272 7202800 484986880 2% /
tmpfs 8193020 4 8193016 1% /tmp
/dev/sda1 1038336 243188 795148 24% /boot
Ve výchozím provedení (výše) se používají kilobajtové bloky. Pro čitelnější
výstup jej spusťte s -BM
nebo -BG
(megabajty a gigabajty) nebo s -h
,
abyste jej nechali vybrat nejvhodnější jednotku.
Vrátíme se k tématu úložišť ještě v posledním cvičení.
Zkontrolujte si zda všemu rozumíte
Archivace a komprese souborů
S výše uvedeným tématem do jisté míry souvisí i způsob, jakým Linux řeší archivaci a kompresi souborů.
Archivace v systému Linux obvykle znamená sloučení více souborů do jednoho (pro snadnější přenos) a kompresi tohoto souboru (pro úsporu místa). Někdy se za archivaci považuje pouze první krok (tj. sloučení).
Ačkoli se tyto dvě činnosti obvykle provádějí společně, Linux je od sebe odděluje, protože to umožňuje kombinovat vhodné nástroje a formáty pro každou část práce. Všimněte si, že v jiných systémech, kde je preferovaným formátem soubor ZIP, jsou tyto činnosti sloučeny do jedné.
Nejpoužívanějším programem pro archivaci je tar
. Původně byl primárně
určen k archivaci na pásky, odtud jeho název: tape archiver. Spouští se
vždy s volbou určující režim práce:
-c
pro vytvoření nového archivu z existujících souborů,-x
pro extrakci souborů z archivu,-t
pro vypsání tabulky souborů uvnitř archivu.
Jméno archivu se zadává pomocí volby -f
; pokud není jméno zadáno, archiv
se čte ze standardního vstupu nebo zapisuje na standardní výstup.
Volba -v
jako obvykle zvyšuje upovídanost programu. Například tar -cv
vypíše jména souborů přidávaných do archivu, tar -cvv
vypíše také atributy
souborů (podobně jako ls -l
). (Vše se vypíše na stderr, takže stdout lze
stále používat pro archiv) Obyčejný tar -t
vypíše pouze názvy souborů,
tar -tv
vypíše i atributy souborů.
Tímto způsobem lze vytvořit nekomprimovaný archiv:
tar -cf archiv.tar adresar_k_archivaci/
Komprimovaný archiv vytvoříte tak, že výstup příkazu tar
předáte příkazu
gzip
:
tar -c adresar_k_archivaci/ | gzip >archiv.tar.gz
Protože je to však velmi časté, tar
podporuje přepínač -z
, který
automaticky volá gzip
, takže můžete psát:
tar -czf archiv.tar.gz adresar_k_archivaci/
tar
má další přepínače pro další (de)kompresní programy: bzip2
, xz
atd.. Nejdůležitější je přepínač -a
, který vybírá (de)kompresní program
podle názvu archivního souboru.
Pokud chcete komprimovat jen jeden soubor, často se používá prostý gzip
bez tar
. Některé nástroje nebo rozhraní API mohou dokonce zpracovávat
soubory komprimované pomocí gzip transparentně.
Chcete-li archiv rozbalit, můžete do tar
rourou poslat gzip -d
(dekomprimovat) nebo použít -z
následujícím způsobem:
tar -xzf archive.tar.gz
Pro usnadnění práce s archivy vám doporučujeme nainstalovat si atool
jako
obecný obal kolem tar
, gzip
, unzip
a mnoha dalších nástrojů.
Například:
apack archive.tar.gz dir_to_archive/
aunpack archive.tar.gz
Všimněte si, že atool
ve výchozím nastavení nepřepisuje existující soubory
(což je další velmi dobrý důvod pro jeho použití).
Pro vypsání souborů v archívu můžete spustit příkaz als
.
find
I když jsou ls(1)
a wildcardy dosti mocné, někdy potřebujeme vybrat
soubory pomocí složitějších kritérií. Zde je užitečný program find(1)
.
Bez argumentů vypíše všechny soubory v aktuálním adresáři, včetně souborů ve vnořených adresářích.
Pomocí parametru -name
můžete omezit vyhledávání na soubory odpovídající
zadanému wildcardu.
Následující příkaz vyhledá všechny soubory alpha.txt
v aktuálním adresáři
a v libovolném podadresáři (bez ohledu na hloubku).
find -name alpha.txt
Proč následující příkaz pro vyhledání všech souborů *.txt
nebude fungovat?
find -name *.txt
find
má mnoho voleb – nebudeme zde opakovat jeho manuálovou stránku, ale
zmíníme se o těch, které stojí za zapamatování.
-delete
okamžitě odstraní nalezené soubory. Velmi užitečné a velmi
nebezpečné.
-exec
spustí daný program pro každý nalezený soubor. Musíte použít {}
pro zadání názvu nalezeného souboru a příkaz musíte ukončit pomocí ;
(protože ;
ukončuje příkazy i v shellu, budete ho muset escapovat).
find -name '*.md' -exec wc -l {} \;
Všimněte si, že pro každý nalezený soubor dojde k novému vyvolání příkazu
wc
. To lze změnit změnou terminátoru příkazu (\;
) na +
. Podívejte se
na rozdíl mezi voláním následujících dvou příkazů:
find -name '*.md' -exec echo {} \;
find -name '*.md' -exec echo {} +
Upozornění
Ve výchozím nastavení vypíše find
jeden název souboru na řádek. Jméno
souboru však může obsahovat i znak nového řádku (!), a proto následující
idiom není 100% bezpečný.
find -options-for-find | while read filename; do
do_some_complicated_things_with "$filename"
done
Pokud chcete být opravdu bezpeční, použijte -print0
a IFS= read -r -d $'\0' filename
, neboť tak se použije jediný bezpečný oddělovač – \0
.
Alternativně můžete výstup find -print0
přesměrovat do xargs --null
.
Pokud však pracujete s vlastními soubory nebo je vzor bezpečný, výše uvedená
smyčka je v pořádku (jen nezapomeňte, že adresáře jsou také soubory a mohou
ve svém názvu obsahovat \n
).
Shell také umožňuje exportovat funkci a volat ji zevnitř xargs
. Vypadá to
ošklivě, ale je to bezpečný přístup, pokud chcete provádět složité operace
nad nalezenými soubory.
my_callback_function() {
echo ""
echo "\$0 = $0"
echo "\$@ =" "$@"
}
export -f my_callback_function
find . -print0 | xargs -0 -n 1 bash -c 'my_callback_function "$@"' arg_zero arg_one
Připomeňme, že funkce lze definovat přímo v shellu a výše uvedené lze skutečně vytvořit interaktivně, aniž by se cokoliv muselo ukládat jako skript.
Úlohy k ověření vašich znalostí
Očekáváme, že následující úlohy vyřešíte ještě před příchodem na cvičení, takže se budeme moci o vašich řešeních na cvičení pobavit.
Učební výstupy a kontrola po cvičení
Tato část podává zhuštěný souhrn základních konceptů a dovedností, které byste měli umět vysvětlit a/nebo použít po každém cvičení. Také obsahují absolutní minimum, které je potřebné pro pochopení navazujících cvičení (a dalších předmětů).
Znalosti konceptů
Znalost konceptů znamená, že rozumíte významu a kontextu daného tématu a jste schopni témata zasadit do většího rámce. Takže, jste schopni …
-
vysvětlit, jaká jsou základní přístupová práva na unixových operačních systémech soubory a pro adresáře
-
vysvětlit co znamenají jednotlivá oprávnění
r
,w
ax
pro běžné soubory a pro adresáře -
vysvětlit, co je to signál v kontextu Linux procesů
-
vysvětlit rozdíl mezi normálním (obyčejným) souborem, adresářem, symbolickým odkazem, souborem zařízení a souborem reprezentujícím stav systému (např. ze souborového systému
/proc
) -
vyjmenovat základní adresáře nejvyšší úrovně v typické instalaci Linuxu a popsat jejich funkci
-
vysvětlit v obecné rovině, jak je strom adresářů vytvořen připojením jednotlivých (souborových) podsystémů
-
vysvětlit, proč Linux zachovává oddělení archivace a komprese (např.
tar
agzip
) -
vysvětlit co je to set-uid bit
-
vysvětlit, co je proces a jak se liší od spustitelného souboru
-
vysvětlit rozdíl mezi vlastnictvím souboru a běžícího programu
-
volitelné: vysvětlit, co je POSIX ACL, jen základní přehled
Praktické dovednosti
Praktické dovednosti se obvykle týkají použití daných programů pro vyřešení různých úloh. Takže, dokážete …
-
zobrazovat a měnit základní přístupová oprávnění souborů
-
pomocí
ps
zobrazit seznam existujících procesů (včetně přepínačů-e
,-f
a--forest
) -
použít
pgrep
pro vyhledání konkrétních procesů -
poslat signál běžícímu procesu
-
použít
htop
k interaktivnímu sledování existujících procesů -
připojit a pracovat s disky pomocí příkazu
mount
(jak s fyzickými tak s obrazy disků) -
získat souhrnné informací o využití disku pomocí příkazu
df
-
použít pro práci se standardními linuxovými archivy
tar
neboatool
-
použít
find
se základními predikáty (-name
,-type
) a akcemi (-exec
,-delete
)
Seznam změn na této stránce
-
2025-04-09: Další příklad na
find
. -
2025-04-09: Oprava učebních výstupů.