Byla vydána verze 1.93.0 programovacího jazyka Rust (Wikipedie). Podrobnosti v poznámkách k vydání. Vyzkoušet Rust lze například na stránce Rust by Example.
Svobodný operační systém ReactOS (Wikipedie), jehož cílem je kompletní binární kompatibilita s aplikacemi a ovladači pro Windows, slaví 30. narozeniny.
Společnost Raspberry Pi má nově v nabídce flash disky Raspberry Pi Flash Drive: 128 GB za 30 dolarů a 256 GB za 55 dolarů.
Technologie Skip pro multiplatformní mobilní vývoj, která umožňuje vývojářům vytvářet iOS a Android aplikace z jediné Swift a SwiftUI kódové základny, se s vydáním verze 1.7 stala open source.
Na GitHubu byl zveřejněn algoritmus "Pro vás" sociální sítě 𝕏.
Byla vydána nová major verze 34.0.0 webového prohlížeče Pale Moon (Wikipedie) vycházejícího z Firefoxu. Přehled novinek v poznámkách k vydání.
Win8DE je desktopové prostředí pro Wayland, inspirované nechvalně proslulým uživatelským rozhraním Metro z Windows 8. Nabízí dlaždicové rozhraní s velkými tlačítky a jednoduchou navigací, optimalizované pro dotyková zařízení. Cílem projektu je přetvořit design operačního systému Windows 8 do funkčního a minimalistického rozhraní vhodného pro každodenní použití na Linuxu.
Laboratoře CZ.NIC vydaly Datovku 4.28.0 a Mobilní Datovku 2.6.0. Hlavní novinkou je ukládání rozpracovaných datových zpráv do konceptů. Datovka je svobodné multiplatformní aplikace pro přístup k datovým schránkám a k trvalému uchovávání datových zpráv v lokální databázi.
Unix Pipe Game je vzdělávací karetní hra zaměřená na děti a rodiče, která děti učí používat unixové příkazy prostřednictvím interaktivních úkolů. Klíčovým prvkem hry je využití symbolu | pro pipeline neboli 'rouru', který umožňuje propojit výstupy a vstupy jednotlivých unixových příkazů, v tomto případě vytištěných na kartičkách. Předpokládá se, že rodič má alespoň nějaké povědomí o unixových příkazech a jejich provazování pomocí |.
… více »PCIem je linuxový framework, který vytváří virtuální zařízení PCIe pomocí technik, které umožňují hostitelskému operačnímu systému rozpoznat tyto syntetické 'neexistující' karty jako fyzické zařízení přítomné na sběrnici. Framework PCIem je primárně zamýšlen jako pomůcka pro vývoj a testování ovladačů bez nutnosti použít skutečný hardware. Dle tvrzení projektu si fungování PCIem můžeme představit jako MITM (Man-in-the-Middle), který se nachází mezi ovladači a kernelem.
Dnes to bude jen taková drobnost. Implementace basename a ověření platného jména proměné.
Basename je součástí coreutils a jeho binárka zpravidla nemá víc jak nějakých 13kB. Standardní použití v shelu většinou vypadá tak, že se zavolá v rámci subshellu a jeho výsledek použije přímo v parametru nějakého příkazu nebo pro přiřazení do proměné. Pokud to v příslušném scriptu uděláme jen párkrát, nic se neděje. Pokud se to však musí udělat třeba tisíckrát, tak už nás může zajímat, že se shell musí forknout a zavolat exec na binárku basename. Přitom samotné vlastnosti bourne shellu dosažení stejného efektu umožňuje. Nejlepšího výsledku (nejrychlejšího provedení) lze samozřermě dosáhnout přímo v kódu.
purename="${1%/}" # bugfix pro adresáře s / nakonci
purename="${purename##*/}" # odstranění adresáře
purename="${purename%$2}" # odstranění přípony (může být třeba i v proměnné nebo parametru)
Pokud si někdo chce udělat funkci, která bude děla to samé jako basename, tak může
basename() { set -- "${1%$2}"; set -- "${1%/}"; echo ${1##*/}; }
Ale má to háček. Při použití této funkce ji stejně zpravidla použijete uvnitř $() a to je zase fork, i když si ušetříte exec(basename). Výjimkou jsou přesměrování typu basename bla/bla/bla.bla >>soubor.txt I když tady by bylo před celým cyklem vhodné udělat exec >>soubor.txt nebo do něj přesměrovat cyklus [for|while] ... done >>soubor.txt
Pro přiřazení do proměnné by bylo vhodnější si udělat speciální funkcičku, která by název proměnné dostala jako parametr, nebo to udělat přímo v kódu jak je uvedeno na začátku. Taková funkcička může vypadat třeba takto:
basenameset()
{
set -- "$1" "${2%$3}"
set -- "$1" "${2%/}"
case "$1" in
[^a-zA-Z]*|*[^a-zA-Z0-9]*|case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while|time);; # špatné jméno proměnné
?*) eval $1=\"${2##*/}\";; # správné jméno proměnné (neprázdné)
esac
}
A tím jsme se dostali oslým můstkem k druhé úloze, ověření platného jména proměnné.
A když už se bavíme o rychlosti, tak pár testíků.
$ for((i=0;$i<10000;i++)); do touch zbytecne_dlouhej_prefix_$i; done
$ cat basename.sh
#!/bin/bash
dir="${1:-.}"
for i in "${dir%/}/"*
do
a="$(basename "$i")"
done
$ cat basename_in_shell.sh
#!/bin/bash
basename() { set -- "${1%$2}"; echo ${1##*/}; }
dir="${1:-.}"
for i in "${dir%/}/"*
do
a="$(basename "$i")"
done
$ cat basenameset.sh
#!/bin/bash
basenameset()
{
set -- "$1" "${2%$3}"
case "$1" in
[^a-zA-Z]*|*[^a-zA-Z0-9]*);;
?*) eval $1=\"${2##*/}\";;
esac
}
dir="${1:-.}"
for i in "${dir%/}/"*
do
basenameset a "$i"
done
$ time ./basename.sh
real 0m17.545s
user 0m5.410s
sys 0m10.020s
$ time ./basename_in_shell.sh
real 0m10.081s
user 0m3.120s
sys 0m5.400s
$ time ./basenameset.sh
real 0m1.461s
user 0m1.350s
sys 0m0.010s
$
Myslím, že je to názorné tak akorát. Nakonec zas až tak moc mini ta laskonka není rozsahem, pouze obsahem.
Tiskni
Sdílej:
$ basename2() { set -- "${1%$2}"; echo ${1##*/}; }
$ basename2 /usr/bin/
$ basename /usr/bin/
bin
$ basenameset /usr/bin/ $tedy prázdný řetězec.
.
$ basenameset a /usr/bin/ $ echo $a
. Když už to někdo chce takto použít, tak si to může fixnout. Pro běžné použití je to zbytečné.
. Kdybys to nazval něco jako basename, tak klidně
.
A čím jiným vykuchat název adresáře než pomocí basename?
$ cat basename.py
#!/usr/bin/env python
import os
for file in os.listdir('.'):
a = os.path.basename('./' + file)
$ time ./basenameset.sh
real 0m3.417s
user 0m3.152s
sys 0m0.096s
$ time ./basename.py
real 0m0.343s
user 0m0.252s
sys 0m0.076s
Takže v Pythonu je to asi tak desetkrát rychlejší. O složitosti nemluvě. Ale je pravda, že to není úplně _přesně_ totéž.
basename_in_shell.sh. Myslým, že se budete dost divit. Mimochodem perlivé #!/usr/bin/env perl use File::Basename; $a=basename($_) foreach (<.*>);je o 5% rychlejší :) (Což bude nejspíš stejně způsobeno o chlup rychlejším natažením perl interpretru než pythonu)
#!/usr/bin/env perl use File::Basename; $a=basename($_) foreach (<*>);což je jen o cca 2% rychlejší.