Tulkki päättää mitä se tekee sille syötetylle tekstijonolle. Vaikka mielestäsi olet antanut tulkille muuttujan niin tulkki tekee oman päätöksensä - kylläkin tarkkojen sääntöjen mukaan.
Muuttuja voidaan tulkita komennoksi - ja sitä komentoa voi käyttää aivan niinkuin se olisi kirjoitettu näppäimillä - ja tuolla komennolla voi olla mitkä parametrit vaan:
Esimerkiksi: a='echo onnistuuhan tämä näinkin'; $a .
Muuttuja voidaan tulkita funktiokutsuksikin. Muuttujana voi olla myös matriisi ja silloin toiminta ratkaisee monta ongelmaa - se on kasapanos sirpalekranaatti sotilaskielellä; ainoa mitä se vaatii on rajaton mielikuvitus. Ja mikäli muuttuja on peräti assosiatiivinen matriisi niin sillä voi tehdä monenmoista muutakin, koodimuunnoksen esimerkiksi.
Muuttujaan voidaan laittaa myös laskukaava. Se tarvitsee avukseen funktiota, esimerkiksi: function ratkaisija () { export BC_LINE_LENGTH=0; echo $1 | tr '[]' '()' | sed 's/x/'$2'/g' | sed 's/e/e(1)/g' | sed 's/pii/4*a(1)/g' | bc -l ;}
- sitten määritellään muuttujaan laskukaava, esimerkiksi: a=x^2+x+1 - ja ratkaistaam a:n arvo kun x on jotakin, esimerkiksi: ratkaisija $a 2
- kaavaksi voi vaihtaa mitä lystäät ja luvut voivat olla millaisia reaalilukuja vaan - pituus on rajoittamaton ja desimaalipikku voi sisäänmenossakin olla.
- tällä tyypillä voit myös kysella vakioiden arvoja:
a=e;ratkaisija $a -> kysytään luonnon vakion e arvoa
a=pii;ratkaisija $a -> kysytään piin arvoa
a=e^pi/s[2]*l[2]; ratkaisija $a # tuo: s[2] on sini 2-radiaania ja l on ln
a=6^5^6-6^6^6;ratkaisija $a
a=$(seq -s '*' 1 10000); ratkaisija $a # 10000 kertoma
- BASH tykkää kyttyrää kaarisuluista ja on pakko käyttää hakasulkuja.
- bc laskee radiaaneissa.
- muutenkin merkintätavat ovat toistaiseksi hieman hakusessa
- jokatapauksessa kun funktion kirjoittaa skriptin alkuun niin laskuja voi suorittaa missävaan kutsulla: ratkaisija melkein_mitä_matemaattista_haluat.
---
Anna käsky: echo 'function x () { x=$(($1)); echo $x ;}' >> ~/.bashrc - ja boottaa kone
Senjälkeen voit kirjoittaa skripteihisi mihin vaan laskun tyyppiä: x 1+1
ja se kirjoittaa näytölle 2 samoinkuin asettaa muuttujan x arvoksi 2 .
- numeroiksi kelpaa kaikki numeroiksi kelvollinen ja +merkin tilalla mitä vaan BASH hyväksyy. Itseasiassa helpompaa kuin muissa kielissä sillä = merkkiä ei tarvita
- tai kirjoita funktio kerro18 sinne .basrc:hen. Senjälkeen voit kirjoittaa laskuja tyyppiä: kerro18 .00900007567899123 900.07000012345678 ja saat vastauksen:
8.1006981175007567491845709040394 joka menee myös muuttujan kerro18 arvoksi
---
Mutta tuo edellinen ei sovi laskuihin joissa voi olla desimaali-lukuja sillä jokainen desimaali-laskutyyppi vaatii oman rutiininsa eikä niiden kaikkien nimi voi olla x. Mutta tässä nimi x johtaakin kuori-funktioon joka jakaa toiminnot eri rutiineihin sen perusteella mikä matemaattinen komento kuori-funktioon tulleessa käskyssä on.
- vanhoista käskyistä muodostetut skriptit ovat niin nopeita ettei niistä muodostettu tällainen kuori-funktio juurikaan hidasta.
- kuori-funktiota on monia muitakin, esimerkiksi matematiikka-ohjelma bc on kuori-funktio todella vaikeakäyttöiselle matematiikka funktiolle dc.
- tuon x:n yleisyydestä: kun selaat minkä tekstin vaan niin siellä ei ole 'koskaan' pientä x:ää jonka kummallakin puolella on välilyönti - rivin alku toimii myös välilyöntinä.
- kaikille funktioile löytyy parempiakin versioita mutta ne ovat paljon iso-kokoisempia.
Toki nämä skriptit ovat isokokoisia mutta kun kirjoittaa ne .bashrc:hen ovat ne jokaisessa skriptissä käytettävissä hakematta niitä kirjastosta. Siitäs saatte, virtuoosit - nyt BASH on perus-laskuissa helppokäyttöisempi ja nopeampi kuin muut kielet. Tosin .bashrc:n sörkkiminen on vaarallista mutta virtuoosien piikkiinhän tämä menee.
- jos botattuaan kirjoittaa mihin tahansa skriptiin: x 1.5*1.5 niin tulos 2.25 kirjoittuu näytölle ja muuttujan: x arvosi tulee myös 2.25. Sitä x:ää ei voi vaihtaa toisen-nimiseksi muutujaksi mutta saahan x:n arvon kopioitua toiseen muuttujaan, esimerkiksi: y=$x
Mutta oikeastaan tästä ei ole kyse eikä siitäkään että jos Chet Ramey auttaisi hieman olisi BASH perus-matikassa skriptauskielten kunkku jo nyt. Mutta tulevaisuutta ei tosiaan tiedä mutta luotan siihen että silloin kauan sitten virtuoosit tekivät monenlaisia muitakin ihmeitä jotka aikanaan paljastuvat varmasti - sitä en kylläkään käsitä miksi he eivät jakaneet suurella vaivalla tehtyjä skriptejään myös muille - sillä on ehdottomasti täysin varma että toimivia skriptejä on ollut silloin pari-kolmekymmentä vuotta sitten. Samaan ihmetysten joukkoon menee se että miksi jo toimiva BASH-skriptien kääntäminen peruttiin.
function x () { apu=$1; etuluku=${apu%%[*/+-]*}; takaluku=${apu##*[*/+-]}
[[ $takaluku$etuluku =~ \. || $apu =~ \/ ]] || { echo $(($1)); return ;} # kokonaisluvut lasketaan kuten ennenkin lukuunottamatta jakolaskua
[[ $takaluku =~ \. ]] || takaluku=$takaluku'.'; [[ $etuluku =~ \. ]] || etuluku=$etuluku'.'
[[ $apu =~ \* ]] && $(echo kerro9 $etuluku' '$takaluku)
[[ $apu =~ \/ ]] && $(echo jaa $etuluku' '$takaluku)
[[ $apu =~ \+ ]] && $(echo summaa18 $etuluku' '$takaluku)
[[ $apu =~ \- ]] && $(echo miinus18 $etuluku' '$takaluku) ;}
function kerro9 () { apu=$1; apu=${apu##*.}; apu2=$2; apu2=$apu${apu2##*.}; desi=${#apu2}; tulos=$((${1//\./}*${2//\./})); echo ${tulos:0: -$desi}.${tulos: -$desi} ;};
function summaa18 () { luku1=$1 ; [[ $luku1 =~ \. ]] || luku1=$luku1.0; desi1=${luku1##*.}; koko1=${luku1%%.*}; luku2=$2; [[ $luku2 =~ \. ]] || luku2=$luku2.0; desi2=${luku2##*.}; koko2=${luku2%%.*}; (( ${#desi1} >= ${#desi2} )) && desipituus=${#desi1} || desipituus=${#desi2} ; desi1=$desi1'000000000000000000000000';
desi2=$desi2'000000000000000000'; desi1=${desi1:0:$desipituus}; desi2=${desi2:0:$desipituus}; apu=$(($desi1+$desi2)); desisumma=${apu: -$desipituus}; ylivuoto=${apu:0: -$desipituus}; [[ $ylivuoto ]] || ylivuoto=0; echo $(($koko1+$koko2+$ylivuoto)).$desisumma ;}
function miinus18 () { luku1=$1 ; [[ $luku1 =~ . ]] && desi1=${luku1##*.} || desi1=0 ; koko1=${luku1%%.*}; luku2=$2; [[ $luku2 =~ . ]] && desi2=${luku2##*.} || desi2=0 ; koko2=${luku2%%.*}
# desimaaliosien tulee olla yhtäpitkät. Lyhyemmän perään kirjoitetaan nollia sillä ne eivät muuta desimaaliosassa arvoa.
(( ${#desi1} >= ${#desi2} )) && desipituus=${#desi1} || desipituus=${#desi2}
desi1=$desi1'000000000000000000'; desi2=$desi2'000000000000000000'
desi1=${desi1:0:$desipituus}; desi2=${desi2:0:$desipituus}
apu=$(($desi1-$desi2))
desisumma=${apu: -$desipituus}; alivuoto=0; [[ $desisumma < 0 ]] && { alivuoto=1; desisumma=$(($desisumma+1000000000000000000)) ;}; echo $(($koko1-$koko2-$alivuoto)).$desisumma ;}
function jaa () { (( ! $# )) && echo funktion ajokäsky on muotoa: jaa 1 2 . Siitä pitää tulla: .5000000000000000000000000000 && sleep 2 && return
[[ ${1//[^.]/} ]] && luku1=$1 || luku1=$1"."
[[ ${2//[^.]/} ]] && luku2=$2 || luku2=$2"."
desimaaliosa1=${luku1##*.}
desimaaliosa2=${luku2##*.}
int1=${luku1%%.*}
int2=${luku2%%.*}
[[ ${#desimaaliosa2} -gt ${#desimaaliosa1} ]] && desi=${#desimaaliosa} || desi=${#desimaaliosa1} #desimaaliosan pituus:
apu=$((${1//\./}%${2//\./}))"000000000000000000"; apu=${apu:0:18}
tulos=$((${1//\./}/${2//\./}))$(($apu/${2//\./})); echo ${tulos:0: -$desi}.${tulos: -$desi} ;}
x 9999.99999*9999.99999 # = 99999999.8000000001
x 12345.67890123456+12345.67 # = 24691.34890123456
x 12345.67890123456-1234.56789012345 # = 11111.11101111111
x 1111111111111111.5/1.51 # = .735835172921265894039735099337
- kaikkien kesto-aika on noin 1 ms.