přejít na obsah přejít na navigaci

Linux E X P R E S, Jak spouštět v Linuxu libovolné soubory

Jak spouštět v Linuxu libovolné soubory

Linux

Že lze v Linuxu spouštět programy pro Linux, ví každý uživatel. Ti pokročilejší znají i skripty. Ale Linux umí stejně jednoduše spouštět prakticky libovolné soubory – například javové archivy nebo programy pro Windows. 


Jak Linux spouští programy

Co to vlastně znamená, když se řekne „spuštění programu“? V Linuxu je potřeba vykonat dva kroky. Nejdřív se vytvoří nový proces – ten je zpočátku kopií nějakého existujícího procesu a liší se jen identifikátorem (PID). Tady to může někdy i skončit. Děje se tak například tehdy, pokud si běžící proces vytváří své kopie, které pro něj vykonávají nějakou práci (takto v určité konfiguraci funguje například webový server Apache).

Většinou ale proběhne i druhá fáze, kdy se spustí nějaký nový program. Jádro si otevře soubor s programem a vybere spouštěč, který se pro spuštění programu použije. Klasické programy (zkompilované do strojového kódu; v Linuxu se standardně používá formát ELF) se namapují do paměti, připojí se k nim potřebné knihovny a začne se vykonávat jejich kód.

Uživatel musí mít samozřejmě k souboru práva ke spuštění. Bez nich jádro spuštění programu nedovolí.

Pokud je spouštěným programem skript, jádro si zjistí požadovaný interpret (cesta k němu je ve skriptu uvedena), ten spustí (viz výše) a skript mu předá. Obecně ale mohou být soubory ke spuštění i jiné a jádro pak vybere jiný spouštěč, je-li k dispozici.

O tom, jaký spouštěč se použije, se jádro rozhoduje podle názvu souboru nebo jeho obsahu. Například klasický spustitelný program obsahuje určitou „signaturu“, podle níž Linux pozná, že je to tento typ souboru. Skript se pozná podle znaků #! na začátku souboru. Za nimi pak následuje cesta k interpretu a případně argumenty, které se mají interpretu předat – viz příklad:

!# /bin/sh -e
exit 0

Tento primitivní skript bude spuštěn interpretem sh a hned skončí s nulových návratovým kódem (úspěšný konec).

Spouštěč binfmt_misc

V Linuxu je kromě specializovaných spouštěčů k dispozici i jeden obecný (binfmt_misc), s jehož pomocí si lze nastavit spouštění souborů prakticky libovolného typu. Soubory lze identifikovat buď podle přípony, nebo podle obsahu (ale ne podle obojího současně). Pro soubor se pak spustí příslušný interpret (jako pro skripty).

Přípona je celkem jasná, v případě obsahu se používá „magické číslo“ umístěné na nějaké pevné pozici v souboru. U binárních souborů to často není problém, u souborů textového charakteru to problém může být, protože neexistuje pevná pozice, na které by se nacházela nějaká data (přestože je třeba soubor XML uvozen konkrétní posloupností znaků, ještě před ní může být například typ dokumentu, odřádkování apod.).

Jak to funguje? Nejdřív je potřeba, aby byl v jádře načten modul binfmt_misc. V některých distribucích je již ve výchozím stavu nainstalován a načítán, jinde je potřeba příslušný balíček doinstalovat ručně (např. v Debianu, Ubuntu a dalších distribucích této větve se jmenuje binfmt-support).

Dalším krokem je konfigurace spouštěče. Modul binfmt_misc si vytváří v souborovém systému procfs (připojeném do adresáře /proc) svůj malý podstrom, který slouží k ovládání spouštěče. Najdete ho v adresáři /proc/sys/fs/binfmt_misc. Jeho obsah může vypadat třeba takto (příklad z distribuce Linux Mint 18.1):

cli 
jar 
python2.7
python3.5
register
status

Začněme od konce. Soubor status obsahuje informaci, zda je spouštěč povolen; zároveň ho lze pomocí zápisu znaků 0 a 1 vypnout, resp. zapnout. Soubor register slouží k registraci typů souborů – do něj se zapisují registrační řetězce. Zbývající soubory už pak příslušejí jednotlivým typům zaregistrovaných souborů.

Když se do některého podíváte, uvidíte něco jako toto:

enabled
interpreter /usr/bin/python2.7
flags: 
offset 0
magic 03f30d0a

To znamená, že je spouštěč povolen, je pro něj použit daný interpret, nepoužívají se žádné příznaky, obsah se testuje na offsetu 0 a hledá se uvedené magické číslo. Uvedený příklad je pro spouštění zkompilovaných souborů jazyka Python 2.7. Pod názvem jar se skrývá spouštění javových archivů.

Jak si zaregistrovat typ souboru

Pokud si chcete zaregistrovat nový typ souboru pro spouštění, je potřeba nejdřív vědět, jak soubor poznat a čím ho spustit. Tak například budeme chtít spustit program mpg123 pro soubory ve formátu MP3. Jsou dvě možnosti, jak to zajistit. Lze vyjít z přípony názvu souboru nebo z magického čísla.

První možnost je jednodušší. Víme, že přípona je „mp3“. Takže už zbývá si jen připravit řetězec, který se pošle jádru k zaregistrování typu. Řetězec má tento obecný formát:

:name:type:offset:magic:mask:interpreter:flags

Takže pro MP3 bude vypadat nějak takto:

:MP3:E::mp3::/usr/bin/mpg123:

Název typu je jasný. Písmeno E říká, že se k rozlišení použije přípona názvu. Offset je prázdný, místo magického číslo se uvede přípona, maska opět prázdná, u interpretu je potřeba uvést celou absolutní cestu ke spustitelnému souboru. Příznaky nejsou využity.

Tento řetězec je potřeba uložit do souboru /proc/sys/fs/binfmt_misc/register (třeba příkazem echo). Tím se typ zaregistruje a zvukové soubory MP3 lze od této chvíle spouštět „přímo“, bez přemýšlení, čím se mají přehrát.

Pozor na to, že soubory musí mít nastaveno právo ke spuštění (což u souborů MP3 standardně nebývá)!

Jak by se spouštění nastavilo pomocí magického čísla? Příslušná čísla (signatury) lze najít například na Wikipedii. Ttentokrát budeme chtít přehrát formát OGG, který může mít různé přípony názvu, ale vždy stejné magické číslo. Přehrávat se bude programem mplayer. Takto bude vypadat řetězec:

:OGG:M:0:4F676753::/usr/bin/mplayer:

Za zmínku stojí písmeno M pro volbu magického čísla, následuje nulový offset a magické číslo formátu.

Řešení složitějších případů

Když budete podrobněji zkoumat signatury formátů, všimnete si, že stejný formát může mít více různých signatur – to je i případ formátu MP3, který se liší podle toho jestli má metadata IDv1 nebo IDv2, případně je zcela bez metadat. To lze vyřešit buď zaregistrováním více typů, nebo se dá rozpoznávání přesunout jinam. Totéž nás nemine v případech, které samotný modul nemůže vůbec vyřešit.

To „jinam“ znamená do interpretu run-detectors, který je součástí balíčku s modulem. Tento interpret bývá umístěn například v /usr/lib/binfmt-support. Tento interpret vznikl původně pro potřeby projektu Mono – vznikl totiž problém s tím, že spustitelné programy pro .NET mají stejou signaturu jako běžné spustitelné programy a nešlo tedy určit, zda se mají spouštět pomocí interpretu Mono nebo Wine. Na jeho fungování se podíváme někdy příště.

Nahoru

Příspěvky

Re: Jak spouštět v Linuxu libovolné soubory
Jirka 22. 02. 2017, 12:10:03
Odpovědět  Odkaz 
Určitě přínosný a zajímavý článek, nicméně spíš pro ty, kteří chtějí jít opravdu do hloubky a zcela preferují práci v konzoli a souvisejících nástrojích...

Já naproti tomu oceňuju, že Linux má při použití prakticky jakéhokoliv "lepšího" GUI možnost "klikoidně" nastavit přímo v systému asociaci souborů velmi podobně jako to mají třeba Windows.

Navíc to obvykle lze udělat minimálně dvěma způsoby: buď přes Nastavení systému - Asociace souborů, nebo ve správci souborů přes pravé myšítko, otevřít čím atd. (teď jsem popsal situaci v KDE a Krusaderu, ale jinde to bude obdobné).

Velmi komfortní záležitost, kterou lze navíc obvykle dodatečně ručně modifikovat tak, aby výsledek byl přesně podle očekávání...
Jak spouštět v Linuxu libovolné soubory
fela 22. 02. 2017, 12:34:23
Odpovědět  Odkaz 
ďakujem za článok. Hoci aj pracujem v linuxe už pekných pár rokov, toto som nevedel.
Tomáš Crhonek Jak spouštět v Linuxu libovolné soubory
Tomáš Crhonek 22. 02. 2017, 16:35:20
Odpovědět  Odkaz 
Je koncepční otázkou, zda by toto mělo být úlohou jádra. Jádro má spouštět nativní binárky (ELF) a to je tak vše.

I u těch skriptů není problém je volat buď ze shellu, který vybere správného interpretra, nebo pokud se mají volat z jiných programů, tak je spouštět přímo přes interpretra.

Sám například do cronu (nebo timeru) vždy uvádím např. python program.py, i když je program.py samozřejmě uvozen správnou hlavičkou a bylo by jej možné spustit "přímo". (Po volání ./program.py se stejně nejdřív spustí řetězec hledání vhodného interpretru a nakonec se stejně spustí ten python program.py - resp. varianta python2.7 nebo python3.5 apod.)

U těch "neprogramových" souborů mi to přijde ještě uhozenější. Jednak je nutné jim dávat práva ke spouštění (i když to nejsou spustitelné soubory, takže nastane bordel v metadatech), ale hlavně z hlediska koncepce by se o toto měl fakt starat shell (obecně vrstva nad jádrem).

Dávat mp3 souboru atribut spustitelný jen proto, aby jádro zavolalo mpg123 soubor.mp3 mě přijde dost uhozené a nevím o případu, kdy je nemožné to zavolat přímo (tedy mpg123 soubor.mp3).

Nehledě na to, že (nejen) grafická uživatelská rozhraní používají k identifikaci typu souboru jeho MIME typ a podle MIME databáze vyberou vhodný program. Ten navíc může být jiný, než program uvedený v binftm. (Nehledě třeba na fakt, že u většiny DE si lze k danému souboru do mime db přiřadit více programů, které s daným formátem umějí pracovat, co u binftm nelze.)

Jinak teda tahle věta hovoří za vše:

"Tento interpret vznikl původně pro potřeby projektu Mono – vznikl totiž problém s tím, že spustitelné programy pro .NET mají stejou signaturu jako běžné spustitelné programy a nešlo tedy určit, zda se mají spouštět pomocí interpretu Mono nebo Wine."

To je fakt super. Místo psaní nativních aplikací pro linux se tam vstrčí Mono nebo Wine a protože to nejde rozlišit (proč?) tak se tam vrazí ještě další vrstva, která určí čím se to má spustit.

Takže tak. Nebudu víc kritizovat, článek je to pěkný, ale podle mě řeší problém, který v linuxu neexistuje a pokud ano, tak je k zamyšlení, proč ten problém vznikl.
Vojtěch Zeisek Jak spouštět v Linuxu libovolné soubory
Vojtěch Zeisek 22. 02. 2017, 17:28:48
Odpovědět  Odkaz 
Článek je hezký, ale přijde mi to zbytečné. Z nadpisu jsem vůbec netušil, o čem to má být. Mnohem užitečnější mi přijde příkaz xdg-open, který podle MIME otevře soubor ve správném programu. Moc šikovná věc. A pokud by ten příkaz byl moc dlouhý, lze mu přidělit nějaký jednopísmenný alias. :-)

Přidat názor

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz