61
Ohjelmointi, palvelimet ja muu edistyneempi käyttö / Vs: Ohjeita shell-skriptaukseen (bash)
« : 23.01.20 - klo:21.59 »
BASH:issa ei ole desimaalilukuja - on vain tekstijonoja joista jotkut voi tulkita desimaaliluvuiksi. Tekstijonoa täytyy usein käsitellä jotenkin ennen tulostamista. Olisi houkuttelevaa käyttää tulostamiseen printf-komentoa sillä se kykenee käsittelemään tulostamisen yhteydessä ja se tulostaa desimaaliluvutkin oikein. Mutta se toimii vain kun kokonaisosan ja desimaaliosan yhteenlaskettu numeromäärä on BASH:issa alle 19, se vaatii joskus desimaalieroittimeksi sen mikä koodisivulla on määrätty (pilkku tai piste) - ja lisäksi se on pikkuisen hidas. Ei voi olla ajattelematta että prntf on heitetty BASH:in rattaisiin jottei desimaalilaskentaa saisi toimimaan hyvin.
Käytettäessä echo:a tulostettavissa luvuissa saa olla moninkertainen määrä numeroita eikä desimaalieroittimen kanssa joudu tappelemaan. Mutta echo ei kykene käsittelemään tulostettavaa mitenkään vaan se tarvitsee apua BASH-skripteiltä ja nämä ovat usein erittäin kookkaita - mutta senlaatuiset skriptit ovat myös hyvin nopeita.
Desimaalilaskennan skriptit ovat vikaherkkiä senlisäksi että ne ovat runsaskoodisia. Ja sellaisissa tilanteissa käytetään normaalisti kirjastoja koodinteossa mutta virtuoosit ovat suhmuroineet BASH:in kirjastoja niin paljon ettei BASH:in kirjastoja juuri kukaan enää käytä. Sentakia on helppoa uskotella että esimerkiksi BASH ei kykene juuri ollenkaan numeronmurskaukseen ilman ulkoisten ohjelmien apua, joten esimerkiksi desimaalilaskentaa pidetään mahdottomana.
Kirjasto on yksinkertaisimmassa muodossaan tiedosto johon on kirjoitettu funktioita. BASH:issa jonkun toisen tiedoston funktiot voi liittää tehtävän skriptin koodiin käskyllä: . tiedoston nimi. Liitoskäsky on tosiaankin pelkkä piste. Aikoinaan BASH:illa oli moniakin kirjastoja - netistä löytyy vieläkin aikamonta (mutta niiden löytäminen on hankalaa). Mutta tapa liittää kirjasto tehtävän skriptin koodiin oli alussa toisenlainen kuin nykyään. Kun liitäntätapaa muutettiin niin kirjastoja lakattiin käyttämästä - vaikka ne toimisivat edelleenkin.
Kirjastofunktion testaaminen on huomattavasti isompi työ kuin tavallisen funktion vaikka niillä ei teoriassa juuri eroa ole - mutta kirjastofunktion täytyy varautua paljon paremmin niihin tapauksiin joita pidetään puolimahdottomina. Jokatapauksessa jokaisessa kirjastofunktiossa on alkuunsa useimmiten naurettaviakin puutteita ja virheitäkin - ja läheskaikkien korjaaminen olisi vuosien urakka komppanialta koodaajia.
Esimerkiksi seuraava tosinopeatoiminen funktio jota kehoitetaan katkaisemaan annettu desimaaliluku määrättävän desimaalimäärän jälkeen pyöristäen oikein. Funktion koodi on nopea huolimatta pituudestaan - eikä tällaista funktiota varmaankaan kukaan viitsisi tehdä jos sitä ei löydy kirjastosta:
Käytettäessä echo:a tulostettavissa luvuissa saa olla moninkertainen määrä numeroita eikä desimaalieroittimen kanssa joudu tappelemaan. Mutta echo ei kykene käsittelemään tulostettavaa mitenkään vaan se tarvitsee apua BASH-skripteiltä ja nämä ovat usein erittäin kookkaita - mutta senlaatuiset skriptit ovat myös hyvin nopeita.
Desimaalilaskennan skriptit ovat vikaherkkiä senlisäksi että ne ovat runsaskoodisia. Ja sellaisissa tilanteissa käytetään normaalisti kirjastoja koodinteossa mutta virtuoosit ovat suhmuroineet BASH:in kirjastoja niin paljon ettei BASH:in kirjastoja juuri kukaan enää käytä. Sentakia on helppoa uskotella että esimerkiksi BASH ei kykene juuri ollenkaan numeronmurskaukseen ilman ulkoisten ohjelmien apua, joten esimerkiksi desimaalilaskentaa pidetään mahdottomana.
Kirjasto on yksinkertaisimmassa muodossaan tiedosto johon on kirjoitettu funktioita. BASH:issa jonkun toisen tiedoston funktiot voi liittää tehtävän skriptin koodiin käskyllä: . tiedoston nimi. Liitoskäsky on tosiaankin pelkkä piste. Aikoinaan BASH:illa oli moniakin kirjastoja - netistä löytyy vieläkin aikamonta (mutta niiden löytäminen on hankalaa). Mutta tapa liittää kirjasto tehtävän skriptin koodiin oli alussa toisenlainen kuin nykyään. Kun liitäntätapaa muutettiin niin kirjastoja lakattiin käyttämästä - vaikka ne toimisivat edelleenkin.
Kirjastofunktion testaaminen on huomattavasti isompi työ kuin tavallisen funktion vaikka niillä ei teoriassa juuri eroa ole - mutta kirjastofunktion täytyy varautua paljon paremmin niihin tapauksiin joita pidetään puolimahdottomina. Jokatapauksessa jokaisessa kirjastofunktiossa on alkuunsa useimmiten naurettaviakin puutteita ja virheitäkin - ja läheskaikkien korjaaminen olisi vuosien urakka komppanialta koodaajia.
Esimerkiksi seuraava tosinopeatoiminen funktio jota kehoitetaan katkaisemaan annettu desimaaliluku määrättävän desimaalimäärän jälkeen pyöristäen oikein. Funktion koodi on nopea huolimatta pituudestaan - eikä tällaista funktiota varmaankaan kukaan viitsisi tehdä jos sitä ei löydy kirjastosta:
Koodia: [Valitse]
function pyöristä_desimaaleissa () { (( ${1//./} > 0 )) && { (( $# == 2 )) && desimaalienluku=$2 || desimaalienluku=0; kokonaisosa=${1%%[,.]*}; desimaaliosa=${1##*[,.]}; (( $desimaalienluku == 0 )) && echo $(($kokonaisosa+$((${desimaaliosa:0} >= 50)))) && return; desimaaliosa=$desimaaliosa"0000000000000000000000";echo $kokonaisosa.$(( ${desimaaliosa:0:$desimaalienluku}+$(( ${desimaaliosa:$desimaalienluku+1} >= 50)) )) ;} || { (( $# == 2 )) && desimaalienluku=$2 || desimaalienluku=0; kokonaisosa=${1%%[,.]*}; desimaaliosa=${1##*[,.]}; (( $desimaalienluku == 0 )) && echo $(($kokonaisosa+$((${desimaaliosa:0} <= 50)))) && return; desimaaliosa=$desimaaliosa"0000000000000000000000";echo $kokonaisosa.$(( ${desimaaliosa:0:$desimaalienluku}-$(( ${desimaaliosa:$desimaalienluku+1} <= 50)) )) ;} ;}
# kutsuesimerkit testaamiseen (kokeillessa leikkaa-liimaaa kaikki päätteeseen yhtenä palasena):
pyöristä_desimaaleissa 1.51515773 0 # pitäisi tulostaa 2
pyöristä_desimaaleissa 1.51515773 # pitäisi tulostaa 2
pyöristä_desimaaleissa 1.51515773 2 # pitäisi tulostaa 1.52
pyöristä_desimaaleissa 12345678901234567890123456789.51515773 2 # pitäisi tulostaa
#12345678901234567890123456789.52
pyöristä_desimaaleissa 1.51515773 3 # pitäisi tulostaa 1.515
pyöristä_desimaaleissa 1.51515773 4 # pitäisi tulostaa 1.5152
pyöristä_desimaaleissa 1.5151577311111151 14 # pitäisi tulostaa 1.51515773111112
pyöristä_desimaaleissa -1.51515773 0 # pitäisi tulostaa -1
pyöristä_desimaaleissa -1.51515773 2 # pitäisi tulostaa -1.51
pyöristä_desimaaleissa -1.51515773 3 # pitäisi tulostaa -1.514
pyöristä_desimaaleissa -1.51515773 4 # pitäisi tulostaa -1.5151
pyöristä_desimaaleissa 1.1 9 # pitäisi tulostaa 1.100000000
: