Cvičení: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.
- Správa uložiště
- Archivace a komprese souborů
- Vývoj softwaru ve virtuálním prostředí
-
Virtuální prostředí pro Python (také známé jako
virtualenv
nebovenv
) - Úlohy před cvičením (deadline: začátek vašeho cvičení, týden 24. dubna - 28. dubna)
- Úlohy po cvičení (deadline: 14. května)
- Učební výstupy
- Seznam změn na této stránce
V tomto cvičení se budeme zabývat dvěma velkými tématy. Nejprve se podíváme na nástroje související se správou úložišť a poté prozkoumáme, jak vyvíjet projekty v jazyce Python ve virtuálním prostředí, které lze snadno distribuovat mezi jednotlivé vývojáře ve velkém softwarovém týmu. Mezi to vmáčkneme krátkou poznámku o kompresi (a archivaci) souborů v systémech Linux.
Správa uložiště
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í 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.
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).
/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ů není omezeno jen na ty fyzické. V další části budeme mluvit o obrazech disků, ale jsou i jiné možnosti. Je možné připojit síťový disk (třeba NFS nebo AFS, které je používané na MFF) nebo dokonce vytvořit síťové blokové zařízení a to připojit.
Práce s obrazy disků (disk images)
Linux má zabudovanou podporu pro práci s obrazy disků. To jest, se soubory, které obsahují zrcadlový obraz skutečného disku. Ve skutečnosti jste s nimi už také pracovali, pokud jste instalovali Linux do virtuálky nebo si stáhli obraz USB disku na začátku semestru.
Linux vám umožní takovýto obraz připojit, jako by to byl fyzický disk a dokonce na něm měnit soubory. To je potřeba pro následující činnosti:
- Vývoj a ladění souborových systémů (což je spíše neobvyklá činnost)
- Vykopírování souborů z obrazů disků virtuálních strojů
- Obnova souborů z poškozených disků (neobvyklé, ale k nezaplacení)
Ve všech případech ale pro připojení obrazu disku stačí systému říct, že má
k souboru přistupovat jako k dalšímu blokovému zařízení (vzpomeňte si na
/dev/sda1
z příkladu výše).
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.
Připojování obrazů disků
Obrazy disků lze připojit téměř stejným způsobem jako bloková zařízení,
pouze je třeba přidat k příkazu mount
volbu -o loop
.
Připomeňme, že mount
vyžaduje práva roota (sudo
), proto musíte
následující příklad provést na svém vlastním počítači, nikoli na některém ze
sdílených počítačů.
Chcete-li si to vyzkoušet, můžete si stáhnout tento FAT obraz disku a připojit jej.
sudo mkdir /mnt/photos-fat
sudo mount -o loop photos.fat.img /mnt/photos-fat
... (prace se soubory v /mnt/photos-fat)
sudo umount /mnt/photos-fat
Případně můžete spustit udisksctl loop-setup
a přidat obraz disku jako
vyměnitelnou jednotku, která se automaticky připojí na plochu:
# Pomoci udisksctl and automatickeho pripojovani v GUI
udisksctl loop-setup -f fat.img
# Tohle vytiskne asi /dev/loop0 ale cislo se muze lisit
# Ted to muzete pripojit v GUI (coz muze probehnout i automaticky)
... (prace se soubory v /run/media/$(whoami)/07C5-2DF8/)
udisksctl loop-delete -b /dev/loop0
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.
df
s du
, které lze použít k odhadu využití místa souborem.
Obvykle se du
spouští jako du -sh DIR
, aby se vypsalo celkové místo
zabrané všemi soubory v DIR
. Pro vypsání velikostí adresářů nejvyšší
úrovně ve vašem $HOME
můžete použít du -sh ~/*
. Buďte však opatrní,
protože prohledání všech adresářů může trvat poměrně dlouho.
Můžete si také všimnout, že využití prostoru hlášené pomocí du
se nerovná
součtu velikostí všech souborů. K tomu dochází proto, že soubory jsou
organizovány v blocích, takže velikosti souborů jsou obvykle zaokrouhleny na
násobek velikosti bloku. Kromě toho také adresáře spotřebovávají určitý
prostor.
Chcete-li zjistit, jak jsou svazky (oddíly) vnořené a která bloková zařízení
jádro rozpoznává, můžete použít příkaz lsblk
. Na sdíleném počítači se
zobrazí následující:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 480G 0 disk
├─sda1 8:1 0 1G 0 part /boot
├─sda2 8:2 0 7.9G 0 part [SWAP]
└─sda3 8:3 0 471.1G 0 part /
To ukazuje, že počítač má 480G disk rozdělený na tři oddíly: malý /boot
pro boostrapování systému, 8G odkládací oddíl a nakonec 470G zbývá pro
systém a uživatelská data. Nepoužíváme samostatný svazek pro /home
.
Mnoho dalších výstupních formátů najdete v manuálové stránce.
Zkoumání a úpravy svazků (oddílů)
Toto téma přenecháme více na pokročilý kurz. Pokud se chcete něco naučit sami, můžete začít s následujícími nástroji:
fdisk(8)
btrfs(8)
mdadm(8)
lvm(8)
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
tar
existující soubory bez jakéhokoli varování.
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í).
Je dobré vždy archivovat jeden adresář. Uživatel, který váš archiv rozbalí, tak nebude mít vaše soubory roztroušené v aktuálním adresáři, ale přehledně připravené v jediném novém adresáři.
Pro vypsání souborů v archívu můžete spustit příkaz als
.
Vývoj softwaru ve virtuálním prostředí
Během předchozích cvičení jsme viděli, že doporučovaným způsobem instalace aplikací (a knihoven nebo datových souborů) na Linuxu je skrze správce balíčků. Ten nainstaluje aplikaci pro všechny uživatele, umožní upgrade celého systému a celkově udržuje systém v rozumném stavu.
Nicméně, ne vždy se systémová instalace hodí. Typický příklad jsou závislosti pro konkrétní projekt. Ty se obvykle neinstalují do systému a to hlavně z následujících důvodů:
- Potřebujete různé verze závislostí pro různé projekty.
- Nechcete si pamatovat, co všechno máte odinstalovat, když na projektu přestanete pracovat.
- Potřebujete určit, kdy dojde k jejich upgradu: upgrade OS by neměl ovlivnit váš projekt.
- Verze, které potřebujete, jsou jiné, než které zná správce balíčků.
- A nebo nejsou vůbec ve správci balíčků dostupné.
Z výše uvedených důvodů je mnohem lepší vytvořit instalaci určenou pro jeden
projekt, která je lépe oddělena (izolována) od zbytku systému.
V tomto ohledu instalace pro uživatele (tj. někam do $HOME
) nemusí
poskytnout takovou míru odstínění, jakou chceme.
Tento přístup podporuje většina rozumných programovacích jazyků a obvykle je najdeme pod názvy jako virtual environment, local repository, sandbox nebo něco podobného (koncepty nejsou 1:1 ve všech jazycích a nástrojích, ale základní myšlenka je stejná).
S virtuálním prostředím (virtual environment) jsou závislosti obvykle instalovány do určeného adresáře ve vašem projektu. Tento adresář potom neverzujeme (Gitem). Překladač/interpret je pak nasměrován na tento adresář.
Instalace do jednoho adresáře nezanese váš systém. Umožní vám pracovat na více projektech s nekompatibilními závislostmi, protože jsou kompletně oddělené.
Každý vývojář si pak může prostředí vytvořit, aniž by do repozitáře přibývaly soubory, které jsou specifické pro danou distribuci nebo operační systém. Ale konfigurační soubor zajistí, že všichni budou pracovat s identických prostředím (tj. stejné verze všech závislostí).
Také to znamená, že noví členové softwarového týmu si mohou prostředí jednoduše připravit právě s pomocí takového konfiguračního souboru.
Instalace závislostí
Uvnitř virtuálního prostředí projektu se obvykle nepoužívají správci balíčků (jako DNF). Místo toho jsou závislosti instalovány správci balíčků daného programovacího jazyka.
Ty jsou obvykle platformě nezávislé a používají vlastní repozitáře. Tyto repozitáře pak obsahují jen knihovny pro daný programovací jazyk. Opět může být těchto repozitářů více a je na vývojářích, jak si vše nastaví
V našem případě budeme vždy instalovat jen do adresářů virtuálního prostředí a do systému jako takového zasahovat nebudeme.
Python Package Index (PyPI)
Zbytek textu se bude zabývat Pythoními nástroji. Podobné nástroje jsou ale dostupné i pro další jazyky: věříme, že ukázky nad Pythonem jsou dostačující pro demonstraci principů v praxi.
Python má repozitář zvaný Python Package Index (PyPI), kde kdokoliv může zveřejnit své Pythonovské knihovny či programy.
Repozitář je možné používat buď skrz webový prohlížeč, nebo přes klienta na
příkazové řádce, který se jmenuje pip
.
pip
se chová podobně jako DNF.
Můžete s ním instalovat, upgradovat nebo odinstalovat Pythoní moduly.
Obvyklý průběh práce
Zatímco konkrétní nástroje se liší podle programovacího jazyka, základní kroky pro vývoj projektu uvnitř virtuálního projektu jsou v podstatě vždy stejné.
- Vývojář naklonuje projekt (třeba z Gitového repozitáře).
- Virtuální prostředí (sandbox) je inicializováno. To obvykle znamená vytvoření nového adresáře s čistým prostředím pro daný jazyk.
- Virtuální prostředí musí být aktivováno. Obvykle virtuální prostředí
musí změnit
$PATH
(nebo nějaký podobný ekvivalent, který je používán pro hledání knihoven a modulů), takže vývojář musísource
(nebo.
) nějaký aktivační skript, aby byly změněny příslušné proměnné. - Potom může vývojář nainstalovat závislosti. Obvykle jsou uloženy v souboru, který lze přímo předat správci balíčků (daného programovacího jazyka).
- Teprve teď může vývojář začít na projektu pracovat. Projekt je kompletně izolován, odstraněním adresáře s virtuálním prostředím odstraníme i veškeré stopy po instalovaných balíčcích.
Každodenní práce pak zahrnuje jen krok č. 3 (nějaký způsob aktivace) a krok 5 (vlastní vývoj).
Poznamenejme, že aktivace virtuálního prostředí obvykle odstraní přístup ke globálně (systémově) nainstalovaným knihovnám. Uvnitř virtuálního prostředí vývojář začíná s čistým štítem: jen s holým překladačem. To je ale velmi rozumné rozhodnutí: zajistí, že libovolná systémová instalace neovlivní nastavení projektu.
Jinými slovy to zlepší opakovatelnost (reproducibility) celého nastavení. Také to znamená, že vývojář musí uvést každou závislost do konfiguračního souboru. I pokud je to závislost, která je obvykle vždy nainstalovaná.
Virtuální prostředí pro Python (také známé jako virtualenv
nebo venv
)
Abychom si mohli bezpečně vyzkoušet instalaci balíčků Pythonu, nastavíme nejprve virtuální prostředí pro náš projekt. Python má naštěstí vestavěnou podporu pro vytvoření virtuálního prostředí.
Ukážeme si to na následujícím příkladu:
#!/usr/bin/env python3
import argparse
import shutil
import sys
import fs
class FsCatException(Exception):
pass
def fs_cat(filesystem, filename, target):
try:
with fs.open_fs(filesystem) as my_fs:
try:
with my_fs.open(filename, 'rb') as my_file:
shutil.copyfileobj(my_file, target)
except fs.errors.FileExpected as e:
raise FsCatException(f"{filename} on {filesystem} is not a regular file") from e
except fs.errors.ResourceNotFound as e:
raise FsCatException(f"{filename} does not exist on {filesystem}") from e
except Exception as e:
if isinstance(e, FsCatException):
raise e
raise FsCatException(f"unable to read {filesystem}, perhaps misspelled path or protocol ({e})?") from e
def main():
args = argparse.ArgumentParser(description='Filesystem cat')
args.add_argument(
'filesystem',
nargs=1,
metavar='FILESYSTEM',
help='Filesystem specification, e.g. tar://path/to/file.tar'
)
args.add_argument(
'filename',
nargs=1,
metavar='FILENAME',
help='File path on FILESYSTEM, e.g. /README.md'
)
config = args.parse_args()
try:
fs_cat(config.filesystem[0], config.filename[0], sys.stdout.buffer)
except FsCatException as e:
print(f"Fatal: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()
Uložte tento kód do souboru fscat.py
a nastavte mu spustitelný bit.
Všimněte si, že fs.open_fs
dokáže otevírat různé souborové systémy a
přistupovat k souborům v nich, jako byste použili vestavěný pythonovský
open
.
V našem programu zadáme cestu k souborovému systému a souboru (z tohoto
filesystému), který má být vypsán na obrazovku (odtud název fscat
, protože
simuluje cat
uvnitř jiného souborového systému).
Zkuste spustit program fscat.py
.
Pokud nemáte v systému nainstalovaný balíček python3-fs
, mělo by dojít k
chybě ModuleNotFoundError: No module named 'fs'
. Je pravděpodobné, že
tento modul nainstalovaný nemáte.
Pokud jste již nainstalovali python3-fs
, odinstalujte jej a zkuste to
znovu (jen pro tuto ukázku). Ale dvakrát zkontrolujte, zda byste
neodstranili nějaký jiný program, který jej může vyžadovat.
Nyní bychom mohli nainstalovat python3-fs
pomocí DNF, ale již jsme
vysvětlili, proč to není dobrý nápad. Mohli bychom jej také nainstalovat
globálně pomocí pip
, ale ani to není nejlepší postup.
Místo toho pro něj vytvoříme nové virtuální prostředí.
python3 -m venv my-venv
Výše uvedený příkaz vytvoří nový adresář my-venv
, který obsahuje čistou
instalaci Pythonu. Neváhejte a prozkoumejte obsah tohoto adresáře.
Nyní je třeba toto prostředí aktivovat.
source my-venv/bin/activate
Váš prompt by se měl změnit: nyní začíná (my-venv)
.
Spuštění souboru fscat.py
přesto skončí s chybou ModuleNotFoundError
.
Nyní nainstalujeme závislost:
pip install fs
To bude chvíli trvat, protože Python bude stahovat také tranzitivní
závislosti této knihovny (a jejich závislosti atd.). Po dokončení instalace
spusťte znovu soubor fscat.py
.
Tentokrát by to mělo fungovat.
./fscat.py
Dobře, vypsalo to chybovou zprávu o požadovaných argumentech. Stáhněte si tento archív a spusťte skript následujícím způsobem:
./fscat.py tar://test.tar.gz testdir/test.txt
Měl by vypsat Test string
, protože je schopen pracovat i s tar archívy
jako se souborovými systémy a vypsat na nich soubory (ověřte, zda je soubor
skutečně k dispozici, buď pomocí atool
, MC, nebo přímo pomocí tar
).
Jakmile jsme s vývojem hotovi, můžeme prostředí deaktivovat voláním
deactivate
(tentokrát bez zadávání zdrojů).
Spuštění souboru fscat.py
mimo prostředí opět skončí chybou
ModuleNotFoundError
.
Instalace balíčků specifických pro Python pomocí pip
Jedno použití pip
u v praxi jsme si již ukázali, ale pip
toho umí mnohem
více. Pěkný přehled všech možností pip
u najdete v článku Using Python’s
pip to Manage Your Projects'
Dependencies.
Zde uvádíme stručný přehled nejdůležitějších pojmů a příkazů.
Ve výchozím nastavení pip install
prohledává registr balíčků
PyPI, aby nainstaloval balíček zadaný na příkazovém
řádku. Nebyli bychom daleko od pravdy, kdybychom řekli, že všechny balíčky
uvnitř tohoto registru jsou jen archivované adresáře, které obsahují
předepsaným způsobem uspořádaný zdrojový kód v jazyce Python.
Pokud chcete tento výchozí registr balíčků změnit, můžete použít argument
--index-url
.
V další části se naučíme, jak z adresáře s kódem vytvořit správný balíček
Pythonu. Za předpokladu, že jsme to již udělali, můžeme tento balíček
nainstalovat přímo (bez archivace/balení) příkazem pip install /path/to/python_package
.
Představte si například situaci, kdy máte zájem o open-source balíček třetí
strany. Tento balíček je k dispozici ve vzdáleném repozitáři git (typicky
na GitHubu nebo GitLabu), ale NENÍ zabalen a zveřejněn v PyPI. Můžete
jednoduše klonovat repozitář a spustit pip install .
. Díky pip VCS
Support se však můžete
fázi klonování vyhnout a balíček nainstalovat přímo pomocí:
pip install git+https://git.example.com/MyProject
Chcete-li aktualizovat konkrétní balíček, spusťte příkaz pip install --upgrade [packages]
.
Nakonec pro odstranění balíčku spustíte pip uninstall [packages]
.
Verzování závislostí
Možná jste už slyšeli o sémantickém verzování. Python používá víceméně kompatibilní verzování, které je popsáno v PEP 440 – Version Identification and Dependency Specification.
Při instalaci závislostí z registru balíčků můžete tuto verzi zadat.
pkgname # latest version
pkgname == 4.2 # specific version
pkgname >= 4.2 # minimal version
pkgname ~= 4.2 # equivalent to >= 4.2, == 4.*
Pravdou je, že specifikátor verze se skládá z řady klauzulí o verzi oddělených čárkami. Proto můžete zadat:
pkgname >= 1.0, != 1.3.4.*, < 2.0
Někdy je užitečné uložit seznam všech aktuálně nainstalovaných balíčků (včetně tranzitivních závislostí). Například jste si nedávno všimli nové chyby ve svém projektu a rádi byste si uchovali přesné verze aktuálně nainstalovaných závislostí, aby váš spolupracovník mohl chybu reprodukovat.
Za tímto účelem je možné použít pip freeze
a vytvořit seznam, který
nastaví konkrétní verze a zajistí tak stejné prostředí pro každého vývojáře.
Doporučujeme je uložit do souboru requirements.txt
.
# Generating requirements file
pip freeze > requirements.txt
# Installing package from it
pip install -r requirements.txt
Balení Pythoních projektů
Řekněme, že jste přišli na super skvělý algoritmus a chcete obohatit svět tím, že se o něj podělíte. Oficiální dokumentace Pythonu nabízí návod krok za krokem, jak toho dosáhnout.
Struktura adresáře balíčků Pythonu
Úplně prvním krokem, než jej můžete publikovat, je jeho transformace do
správného balíčku Pythonu. Musíme vytvořit soubory pyproject.toml
a
setup.cfg
. Tyto soubory obsahují informace o projektu, seznam závislostí a
také informace pro instalaci projektu.
V repozitáři
fscat
najdete balíček Pythonu se stejnou funkčností, jakou má náš předchozí skript
fscat.py
.
setup.cfg
.
Zkuste si tento balíček (s pomocí podpory VCS) následujícím příkazem nainstalovat:
pip install git+http://gitlab.mff.cuni.cz/teaching/nswi177/2023/common/fscat.git
Možná jste si všimli, že soubor setup.cfg
obsahuje sekci
[options.entry_points]
. Tato sekce určuje, jaké jsou skripty váš projekt
aktuálně obsahuje. Všimněte si, že po spuštění výše uvedeného příkazu
můžete spustit příkaz fscat
přímo. Pip pro vás vytvořil obalový skript a
přidal jej do $PATH
virtuálního prostředí.
fscat tar://tests/test.tar.gz testdir/test.txt
Nyní balíček odinstalujte pomocí:
pip uninstall matfyz-nswi177-fscat
Naklonujte repozitář do místního počítače a vstupte do jeho adresáře. Nyní spusťte:
pip install -e .
pip install -e
vytvoří editovatelnou instalaci pro snadné
ladění. Namísto kopírování vašeho kódu do virtuálního prostředí nainstaluje
pouze věc podobnou symlinku (ve skutečnosti soubor fscat.egg-link
, který
má podobný účinek na mechanismus Pythonu pro vyhledávání modulů) odkazující
na adresář s vašimi zdrojovými soubory.
Sestavení Pythoního balíčku
Když už máme správnou adresářovou strukturu, zbývají nám už jen dva kroky k jejímu zveřejnění v registru balíčků.
Nyní připravíme distribuční balíčky pro náš kód. Nejprve nainstalujeme
balíček build
příkazem pip install build
. Poté můžeme spustit příkaz
python3 -m build
V podadresáři dist
se vytvoří dva soubory:
-
matfyz-nswi177-fscat-0.0.1.tar.gz
– archiv zdrojového kódu -
matfyz_nswi177_fscat-0.0.1-py3-none-any.whl
– wheel soubor, což je sestavený balíček (py3
je požadovaná verze Pythonu,none
aany
říkají, že se jedná o balíček nezávislý na platformě).
Nyní se můžete přepnout do jiného virtuálního prostředí a nainstalovat
balíček pomocí pip install
package.whl.
Publikování Pythoního balíčku
Pokud si myslíte, že by balíček mohl být užitečný i pro další lidi, můžete jej zveřejnit v Python Package Index. To se obvykle provádí pomocí nástroje twine. Přesný postup je popsán v části Uploading the distribution archives.
Nástroje vyšší úrovně
Na pip
a virtualenv
můžeme pohlížet jako na nízkoúrovňové nástroje.
Existují však i nástroje, které oba tyto nástroje kombinují a přinášejí
větší komfort při správě balíčků. V jazyce Python existují přinejmenším dvě
oblíbené možnosti, a to Poetry a
Pipenv.
Interně tyto nástroje používají pip
a venv
, takže stále můžete mít
nezávislé pracovní prostory a také možnost nainstalovat konkrétní balíček z
Python Package Index (PyPI).
Úplné představení těchto nástrojů je mimo rámec tohoto kurzu. Obecně se řídí stejnými principy, ale přidávají některé funkce navíc, které je hezké mít. Ve stručnosti lze uvést tyto hlavní rozdíly:
- Mohou zmrazit určité verze závislostí, takže se projekt sestaví na všech
počítačích stejně (pomocí souboru
poetry.lock
). - Balíčky lze odstranit spolu s jejich závislostmi.
- Inicializace nového projektu je jednodušší.
Ostatní jazyky
Ostatní jazyky mají vlastní nástroje s podobnými funkcemi:
Úlohy před cvičením (deadline: začátek vašeho cvičení, týden 24. dubna - 28. dubna)
Následující úlohy musí být vyřešeny a odevzdány před příchodem na vaše cvičení. Pokud máte cvičení ve středu v 10.40, soubory musí být nahrány do vašeho projektu (repozitáře) na GitLabu nejpozději ve středu v 10.39.
Pro virtuální cvičení je deadline úterý 9:00 (každý týden, vždy ráno, bez ohledu na možné státní svátky apod.).
Všechny úlohy (pokud není explicitně uvedeno jinak) musí být odevzdány přes váš repozitář na úkoly. Pro většinu úloh existují automatické testy, které vám mohou pomoci zkontrolovat úplnost vašeho řešení (zde je popsáno jak číst jejich výsledky).
11/romandate.py
(100 bodů, skupina devel
)
Napište program v jazyce Python, který pomocí balíčků roman
a dateparser
vypíše uživatelem zadané datum římskými číslicemi.
Program nejlépe vystihují níže uvedené příklady (za předpokladu, že byly provedeny 24. dubna 2023).
./romandate.py
XXIV.IV.MMXXIII
./romandate.py 2021-01-01
I.I.MMXXI
./romandate.py 40 years ago
XXIV.IV.MCMLXXXIII
Testy předpokládají, že jsou již spuštěny ve virtuálním prostředí, kde jsou nainstalovány výše uvedené balíčky (při spuštění na GitLabu se tyto dva balíčky nainstalují automaticky).
Dodané testy kontrolují pouze přesná data (až je budeme hodnotit po deadline, vložíme do nich aktuální datum).
Nezapomeňte zkontrolovat, že vaše řešení také funguje
- když je spuštěno bez parametrů (čas nyní, tedy
now
) - když je spuštěno s relativními daty jako třeba
5 days ago
Úlohy po cvičení (deadline: 14. května)
Očekáváme, že následující úlohy vyřešíte po cvičení, tj. poté, co budete mít zpětnou vazbu k vašim řešením úloh před cvičením.
Všechny úlohy (pokud není explicitně uvedeno jinak) musí být odevzdány přes váš repozitář na úkoly. Pro většinu úloh existují automatické testy, které vám mohou pomoci zkontrolovat úplnost vašeho řešení (zde je popsáno jak číst jejich výsledky).
11/project-name/
(70 bodů, skupina devel
)
Připravte Pythoní balíček, který poskytuje příkaz project-name
, který se
pokusí automaticky určit název projektu.
Podobně jako v jednom z prvních úkolů v tomto kurzu program hledá v
souborech README.md
a README
první neprázdný řádek (opět odstraní
přebytečné bílé znaky a úvodní #
v souborech *.md
).
Pokud není k dispozici README.md
ani README
, program se pokusí najít
nejvyšší adresář projektu Git (zvažte použití parametru konstruktoru
search_parent_directories=True
a vlastnosti working_tree_dir
u typu
Repo
z GitPython) a vypíše jeho jméno
(bez cesty).
Pokud aktuální adresář není součástí projektu Git, program vypíše jméno aktuálního adresáře (opět bez cesty).
Očekáváme, že následující postup bude fungovat (pravděpodobně nejlépe ve virtuálním prostředí).
project-name
# Prints 'NSWI177 Submission Repository'
cd 01
project-name
# Prints 'student-LOGIN'
cd ../../
project-name
# Prints directory name of the parent directory of your submission repository clone
Očekáváme, že si vytvoříte správný podadresář src
a správně uspořádáte
svůj balíček pomocí souboru setup.cfg
atd.
Klidně použijte části svého řešení úlohy 01.
Automatické testy vždy vytvoří nové virtuální prostředí pro každý testovaný
případ. Což je fajn pro závěrečnou kontrolu. Ale je též možné testy spustit
v aktivovaném virtuálním prostředí, kdy očekávají, že příkaz project-name
už je nainstalován. A sice přes nastavení NSWI177_LAB11_NO_INSTALL=true
(takže pak přeskočí část pip install 11/project-name
, což je docela dost
zrychlí):
env NSWI177_LAB11_NO_INSTALL=true ./bin/run_tests.sh 11-post/project_name
11/fat.txt
(30 bodů, skupina admin
)
Soubor linux.ms.mff.cuni.cz:~/lab11.fat.img
je obraz disku s jediným
souborem.
Vložte jeho (dekomprimovaný) obsah do 11/fat.txt
(do GitLabového
repozitáře).
Soubor ~/lab11.fat.img
vám můžeme vytvořit jen tehdy, když se k počítači
alespoň jednou přihlásíte.
Pokud tam soubor nemáte, počkejte, prosím, do druhého dne.
Nenechávejte úlohu na poslední chvíli a ozvěte se, pokud se soubor neobjevil, jak je popsáno výše.
Učební výstupy
Učební výstupy podávají 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, co je to obraz disku
-
vysvětlit, proč nejsou zapotřebí žádné speciální nástroje pro práci s obrazy disků
-
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, co jsou požadavky (závislosti na knihovnách)
-
vysvětlit základy sémantického verzování
-
vysvětlit, jaké jsou výhody a nevýhody instalace závislostí pro celý systém vs jejich instalaci ve virtuálním prostředí
-
poskytnout vysokoúrovňový přehled virtuálních prostředí
-
vysvětlit výhod a nevýhody uvedení tranzitivních závislostí ve srovnání s uvedením jen přímých
-
vysvětlit výhody a nevýhody uvedení přesné verze nebo jen minimální
-
vysvětlit, proč Linux zachovává oddělení archivace a komprese (např.
tar
agzip
)
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 …
-
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
-
vytvořit nové virtuální prostředí (pro Python) pomocí
python3 -m venv
-
aktivovat a deaktivovat virtuální prostředí
-
nainstalovat závislosti projektu do virtuálního prostředí pomocí
pip
-
vyvíjet program uvnitř virtuálního prostředí (s projektem používajícím
setup.cfg
apyproject.toml
) -
nainstalovat projekt, který používá
setup.cfg
-
volitelné: použít
lsblk
ke zjištění informací o úložných zařízeních -
volitelné: připravit projekt Pythonu pro instalaci
Seznam změn na této stránce
-
2023-04-17: Výskyty
python
nahrazenypython3
kvůli větší přesnosti. -
2023-04-20: Přidány automatické testy pro úlohy před cvičením.
-
2023-04-28: Přidány automatické testy pro úlohy po cvičení.
-
2023-06-14: Poznámka o připojování disků ve VirtualBoxu.