Kirjoittaja Aihe: Ohjeita shell-skriptaukseen (bash)  (Luettu 376510 kertaa)

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11481
    • Profiili
    • Tomin kotisivut
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #140 : 22.02.13 - klo:23.42 »
Siirsin skriptiajuriviestejä omaan ketjuunsa. Toivottavasti tästä ketjusta ei tullut vaikeaselkoista sen takia. Yritin valikoida oikeat viestit, mutta foorumisoftan rajoituksista johtuen en saanut kaikkia viestejä (ainakaan vielä) siirrettyä.

Uusi aihe tuolla: http://forum.ubuntu-fi.org/index.php?topic=44605.0
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #141 : 30.03.13 - klo:07.39 »
BASH-skripteissä voi olla tulosteissa ja editoreissa näkymättömiä kontrollimerkkejä jotka saattavat tehdä skriptistä toimimattoman. Joskus myös tekstijono voi kiukutella.

varsinaisten kontrollimerkit ovat ascii-koodeiltaan välillä 00-1f hexadesimaalisina ja niiden "BASH-merkintä" on välillä \x00-\x1f.
osan kontrollimerkeistä voi poistaa tiedostosta käskyllä: for i in {01..19} 0b 0c 0d 0e 0f 1a 1b 1c 1d 1f; do apu='\x'$i; sed -i "s/${apu}//g" tiedostonnimi; done
kokeile: echo -e '#\x1d!/bin/bash\x01 koe\x0atoinen\x0d rivi' > delme; cat -v delme;  for i in {01..19} 0b 0c 0d 0e 0f 1a 1b 1c 1d 1e 1f; do apu='\x'$i; sed -i "s/${apu}//g" delme; done; cat -v delme

- kontrollimerkki \x00 on kielletty, se on kuulemma sed-sääntöjen vastainen
- ääkköset muuten säilyy vaikka tuloksen perusteella voisikin nopeasti päätellä että hassusti käy.
- käsky saattaa poistaa jotain tärkeääkin, joten suhtaudu varoen.

Mutta mitä enemmän tuota kontrollimerkki-ongelmaa tutkin niin sitä enemmän alkaa tuntua siltä, että vian nimi on hiukan väärin sillä eivät ne invalidisoivat merkit ole varsinaisesti kontrollimerkkejä vaan editorien lisäämiä "kontrolli-merkkejä" jotka yleensä alkavat: M- tai: C- . Myöskin ääkköset tuovat niitä mukanaan, ja taitaa olla niin että joskus käy ääkkösten poistamisessa niin että ääkkönen lähtee ja "kontrollimerkit" jäävät.

Näiden kontrolli-merkkien metsästämiseen sopii parhaiten käsky: cat -v skriptitiedostonNimi
- tai jos etsii kontrollimerkkejä tekstijonosta löytää ne käskyllä: echo "tekstijono" | cat -v
- jos skriptin listaus olisi muuten kovin pitkä voi sitä rajoittaa: cat -v skriptitiedostonNimi | grep M-   . Se selventää muutenkin.

Nuo kontrollimerkit saa poistettua vaikka gedit:illä ja kai muillakin editoreilla:
1. katso missä ne kontrollimerkit ovat käskyllä: cat -v skriptitiedostonNimi | grep -e M- -e C-
2. lue tiedosto editoriin, poista kontrollimerkkien jälkeinen ja edellinen merkki - sitten kirjoita ne heti takaisin ja talleta tiedosto. Kontrollimerkit hävisivät.

Ääkköset sotkevat hommaa: niiden merkkinä on "kontrollimerkkejä".

Kontrollimerkit sha-bangissa ( #!/bin/bash on yksi sha-bang, mutta niitä on monta samantapaista):
Jos sha-bang puuttuu tai on vahingittunut niin käytetään oletusta, esimerkiksi #!/bin/sh
Yksi sha-bang:in vahingoittumismuoto on se, että merkkien #! välissä on jotakin.
Sha-bangin tulee myös alkaa rivin alusta.
**
Löysinpä netistä yhdenrivin skriptin, joka etsii osoitettavasta kansiosta ja sen alikansioista tiedostoja jotka ovat täysin samoja lukuunottamatta nimeä. Tiedostot voivat myöskin olla eri kansioissa.
- samuus lasketaan md5sum:masta. Jos md5sum:maan on tyytymätön niin voi käyttää mitähyvänsä muuta hyväksikatsomaansa funktiota tai vaikkapa tehdä oman . Mutta nyt skripti on:
find polku_mistä_kansiosta_lähtien_eroja_etsitään -type f -exec md5sum '{}' ';' | grep -v mistä_kansiosta_ei_tuloksia_näytetä | sort | uniq --all-repeated=separate -w 33 | cut -c 35-
- skriptin oikeellisuus on tarkistettu toistaiseksi pintapuolisesti enkä ihmettelisi jos siinä ilmenisi myöhemmin kummallisia piirteitä. Mutta eihän kyse olekaan siitä toimiiko skripti oikein sillä siitä voi olla varma että korjaus löytyy.
- täytyihän sitä vähän parsia.

Eihän tuo skripti huippunopea ole: 15.000 tiedoston (koko kaikkiaan 100M) kanssa se kesti 32 sekuntia.
Kun tarvitaan laskuria käytetään BASH:issa yleensä BC:tä eikä vanhempaa vaikeakäyttöistä DC:tä. DC on kuitenkin paljon parempi näytös-luonteisissa tehtävissä joita nykyään vaaditaan - esimerkiksi piin arvon laskemisessa 100 000 numeron tarkkuudella tai laskettaessa mikä on 2000 kertoman arvo.
**
Skriptaamisen taito on nopeasti häviämässä. Tämä johtaa väkisin tehtyihin huonoihin skripteihin. Esimerkiksi yksi awk-skripti: kaveri pyysi apua foorumilla ja saikin paljon vastauksia. Jo ensimmäinen vastaus esitti toimivan skriptin, mutta myöhemmissä vastauksissa oli aina jotakin uutta jättäen pois jonkun hölmöyden. Kunnes lopulta eräs foorumilainen esitti todella sujuvan skriptin sanoen: miksi et tekisi kaikkea awk:issa ? On turhaa poiketa vähänväliä BASH_issa, putkittaa, käyttää apu-ohjelmia ym. kun kaiken voi tehdä awk:issa.

Onhan "väkisin tehty" skripti paljon parempi kuin se ettei skriptiä ole ollenkaan. Teen niitä väkisintehtyjä itsekin kokoajan sillä kun taito ei riitä niin taito ei riitä eikä sille nopeasti mitän voi. Mutta jotenkin vääristynyt nykytilanne on.
**
Pääsin awk:in tutkimisessa vaiheeseen matriisioperaatiot. Awk-skriptit "juoksevat rinkuloita matikka-ohjelmien ympärillä" ja teoriassa niiden tekeminen on helppoa, teoriassa onnistuisi minultakin. Mutta käytännössä niiden tekeminen ei minulta onnistu, sillä en osaa edes nimityksiä vaan joudun etsimään määritelmiä kaikkeen eikä ole hajuakaan mitä mistäkin pitäisi tulokseksi tulla. 

Mutta ne vähäiset esimerkit joita löysin osoittavat että niillä tekee salaman-nopeasti mitävaan - niinkuin matriisi-operaatiolla käsinkin, mutta sitä puuduttavaa a3b7c8 esitystä ei joudu tekemään. Mikä työkalu awk skriptaavalle matemaatikolle onkaan !
**
Päätteessä voi muutamia näppäimiä (kaiketi f5-f9 mutta riippuu distrosta) muokata:
- avaa pääte ja paina nappulaa jonka painamisen haluat tulostavan jonkun pitkän litanian tekstiä tai käskyn. Katso mitkä merkit tulee näytölle.
- anna käsky:   bind '"<merkit>":"teksti"'   
- jos teksti on käsky niin tekstin perään kirjoitetaan \n   
- Siis esimerkiksi:  bind '"7~":"/home/petteri/OMATSKRIPTIT/Etsi_ohjeista\n"'   huomautus: 7~ tuli minulla kun painoi f6
- ilmeisesti näppäimen ohjelmointi ei toimi mikäli näppäin on käyttöjärjestelmässä määritelty tekemään jotakin.
- käskyn voi laittaa .bashrc tiedostoon. Silloin voi kuulemma jättää bind:in pois.
**
eihän ne man-sivut enää ole ihan kunnossa ja kannattaakin hakea man-sivut netistä jos kyseessä ei ole ihan pikkujuttu.
Mutta pikkuhommissa tulee käytettyä koneen omaa man-käskyä ja sen toiminta on ihottava. Kypsyin lopulta koko man-käskyyn ja tein mann-käskyn joka hakee man-sivun editoriin, jossa sitä voi selata ja ctrl-f toimii myös. Käskyn saa kun .bashrc-tiedostoon kirjoittaa: function mann { man $1 > delme; gedit delme;wait;rm delme ; }
- muutoksen saa heti toimimaan kun käskee: . ~/.bashrc
- info-sivut ovat hieman paremmat kuin man-sivut. Info-sivujen lukemiseen tarkoitettu sovellus nimeltään pinfo on tutustumisen arvoinen.
**
AWK:in matemaattiset kyvyt ovat mielettömän hyvät. Kaikien mielestä hyvän esimerkin etsiminen on kylläkin niin vaikeaa niin että esitetään "koulu-esimerkki Fibonacci-lukusarjan laskemisesta":  seq 50 | awk 'BEGIN {a=1; b=1} {print a; c=a+b; a=b; b=c}'
- lasku kestää 6 ms - ei ole mitään järkeä parantaa C:llä.

Tai lasketaanpa taulukon sarakkeen normaalipoikkeama:
awk '{sum+=$1; sumsq+=$1*$1} END {print sqrt(sumsq/NR - (sum/NR)^2)}' tiedosto
- kyllähän siinäkin saattaa kulua ihan monta millisekuntia

« Viimeksi muokattu: 30.01.15 - klo:16.51 kirjoittanut petteriIII »

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #142 : 07.05.13 - klo:15.43 »
Niinkuin BASH:issa kaikki muukin niin seuraavat matriisi-toiminnot voidaan määritellä monilla tavoilla.

Koodia: [Valitse]
#!/bin/bash
function tulosta_matriisi () {
[[ ! $(eval echo \${$1[*]}) ]] && echo matriisi $1 on määrittelemätön && echo && return # esimerkiksi kirjoitusvirhe nimessä aiheuttaa tämän
(echo -n "Matriisin $1 jäsenten arvot    : "; eval echo -e \${$1[@]^^}          # ^^ muuttaa arvot suurille kirjaimille. Muuttaminen pienille kirjaimille olisi ,,
echo -n "Matriisin $1 jäsenten osoitteet : "; eval echo \${!$1[*]}) | column -t # voi ne poiskin jättää
echo -n "Matriisin $1 jäsenienluku           :  "; eval echo  \${#$1[@]}
echo
}

declare -A matriisi1 # Assosiatiivinen matriisi tarvitsee ilmoittaa, mutta tavallista matriisia ei tarvitse ilmoittaa, mutta jos sen haluaa ilmoittaa niin tuo parameri on -a
matriisi1[yksi]=ensimmäinen
matriisi1[kaksi]=toinen
matriisi1[kolme]=kolmas

matriisi2[7]=2  # matriisin jäsenien osoitteiden ei tarvitse alkaa nollasta ja osoitteet voivat pomppiakin eikä muistia kulu väliin jääneisiin osoitteisiin. Myöskään
matriisi2[4]=1  # matriisin jäseniä ei tarvitse antaa järjestyksessä ja silti ne tulevat tulosteeseen järjestyksessä.
matriisi2[123]=3
matriisi2[334455]=4

matriisi3=(minä, sinä, '"Hentun Liisa"', '"Puntun Paavo"', '"Kapakka Lassi"' ja '"Mylläri Matti"' montako meittiä oli?)
# mikäli matriisin jäsenessä on välilyöntejä on jäsenen molemmin ouolin laitettava lainausmerkki. Se kyllä hieman sekoittaa tulostetta.
# mikäli vielä halutaan ne tulosteeseen selvästi erotettuina täytyy käyttää kovan- ja pehmeän lainausmerkin yhdistelmää

matriisi4=({a..z})

tulosta_matriisi matriisi1
tulosta_matriisi matriisi2
tulosta_matriisi matriisi3
tulosta_matriisi matriisi4
tulosta_matriisi matriisi5

# tässä on kaksi tehtävää ja voit tarkastella niiden suorittamista poistamalla kommentit neljästä tämän lohkon viimeisestä lauseesta ja kommentoimalla viimeisen lohkon
# 1.matriisin tiettyjen jäsenien tekeminen määrittelemättömiksi ja tulostaminen - kiinnitä huomiosi osoitteisiin
# 2.määrittelemien jäsenien poistaminen ja tulostaminen taas - kiinnitä taas huomiosi taas osoitteisiin
#for ((i=0; i<=9; i++)); do unset "matriisi4[$i]"; done
#tulosta_matriisi matriisi4
#matriisi4=( "${matriisi4[@]}" ) # matriisin jäsenten uudelleen numerointi siten, että ensimmäisen jäsenen osoite on 0 ja seuraavien jäsenten osoitteet aina 1 suurempi
#tulosta_matriisi matriisi4

# tämä vastaa noita neljää edellistä kommentoitua lausetta; työ on pakko suorittaa näin muissa kielissä sillä sparse tyyppistä matriisia ei niissä ole. 
# BASH:_issa sensijaan voi tehdä kummin vain.
matriisi4=("${matriisi4[@]:9:25}") # siis vain arvot 9-25 otetaan ja osoitteet uudelleen-numeroidaan samalla
tulosta_matriisi matriisi4
« Viimeksi muokattu: 31.01.15 - klo:04.57 kirjoittanut petteriIII »

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #143 : 23.05.13 - klo:14.38 »
Mitä useilla man sivuilla oleva "C-kieli" on, mikä käyttötarkoitus niillä on ? Onko kyse vain pilalle-dokumentoinnista ?

Esimerkiksi näppäile: man wait ja vertaa tulosta siihen minkä saat esimerkiksi nettisivulta: http://ss64.com/bash/wait.html

« Viimeksi muokattu: 30.01.15 - klo:16.58 kirjoittanut petteriIII »

janne

  • Käyttäjä
  • Viestejä: 5150
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #144 : 03.06.13 - klo:20.57 »
Mitä useilla man sivuilla oleva "C-kieli" on, mikä käyttötarkoitus niillä on ? Onko kyse vain pilalle-dokumentoinnista ?

Esimerkiksi näppäile: man wait ja vertaa tulosta siihen minkä saat esimerkiksi nettisivulta: http://ss64.com/bash/wait.html

Jos kirjoitat:
Koodia: [Valitse]
$ man man
huomaat, että man-käsky hakee dokumentteja useista eri osioista. Koska wait ei ole erillinen komento, vaan bashin sisäänrakennettu käsky, ei waitia löydy osiosta 1. Samalla nimellä löytyy kuitenkin järjestelmäkutsu, osiosta 2, jolloin man näyttää ohjeistuksen sen käyttöön.

Kyse on siis siitä, että man näyttää ensimmäisen relevantin osuman, riippumatta siitä mitä komentotulkkia sattuu käyttämään.

Otetaan vielä esimerkki. Järjestelmästä löytyy hyvin suurella todennäköisyydellä komento stat. Sattumoisin samalla nimellä löytyy myös systeemikutsu. Jos siis kirjoitetaan:

Koodia: [Valitse]
$ man stat
näyttää man ohjeistuksen ensimmäisestä osiosta löytyvälle suoritettavalle komennolle stat, kun taas järjestelmäkutua kaipaava joutuu ohjeistustaan etsiessään kirjoittamaan:

Koodia: [Valitse]
$ man 2 stat
« Viimeksi muokattu: 03.06.13 - klo:21.03 kirjoittanut janne »
Janne

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #145 : 04.06.13 - klo:06.29 »
Selväksi tuli, tattista selityksestä. "Onnen lähteistä kumpuaa kitkeryys" vai mitenkä se oli. Kyllä tämä torpedo yhden BASHin upottaa.  

Sivulla www.manpagez.com tämä on kivasti esitetty, sillä siellä kerrotaan minkätyyppinen man-sivu tullaan esittämään, minkätyyppinen löytyy.
**
Man sivuilta voi muuten etsiä: esimerkiksi kun haluat tietoa readline-käskystä voit etsiä uusia näkökulmia etsimällä sivulta: man bash
- etsiminen: kirjoita kauttaviiva ja perään readline. kun painat enter esiin tulee ensimmäinen viittaus. Viittaukset eteenpäin: paina n  ;ja viittaukset taaksepäin: paina N
**
Koodia: [Valitse]
XOR on BASH:in perusfunktio. Se on niin tärkeä että merkki ^ määrättiin merkitsemään XOR:ia ja potenssiin korotus joutui tyytymään merkiin:
** . Kuvaus XOR:in toiminnasta:

Otetaanpa esimerkiksi: 1 XOR 4 . "BASH-kielisenä" se esitetään: echo $((1^4))
ja se antaa tulokseksi 5. Selvitys: BASH: matematiikka toimii binääriluvuilla. BASH olettaa, että mitkä numerot syötätkin niin ne on esitetty
desimaalisina joten se muuttaa ne binäärimuotoon. Siis:         1=            001
                                                                4=            100
                                                                -----------------
                                                                XOR=          101  

- siis XOR suoritetaan bitti kerrallaan lukujen binääriesityksen vastinbiteille.
- lukuja voi olla useampiakin kuin kaksi.
- BASH olettaa että haluat tulosteidenkin olevan desimaaliarvoja. Ja binääriluku 101 on desimaalisena 5.
- muuten BASH ei edes osaa esittää tulosta binäärisenä vaan sitävarten täytyy tehdä 12-rivinen skripti tai käyttää käskyryhmää:
  echo "obase=2; $((1^4))" | bc
- saman logiikan mukaan toimivat myös & ja: |  (=and ja or)
- mutta tässä esitetty XOR on bitwise-XOR eikä 'tavallista' XOR:ia ole vaivauduttu tekemään vaan se täytyy koodata itse - koodaustapa on esitetty lauseessa
jossa etsitään sataa pienemmät luvut jotka ovat jaollisia kuudella tai seitsemällä mutta eivät molemmilla:
for n in {1..100}; do  [[ $(($n%6)) = 0 || $(($n%7)) = 0 ]] && ! [[ $(($n%6)) = 0 && $(($n%7)) = 0 ]] && echo $n kelpaa ; done
**
Grep on kymmeniä kertoja hitaampi utf-8:lla kuin localella C. Enpä ole vielä kokeillut kun utf-8:lla nopeus on ollut toistaiseksi riittävä. Asiasta kerrotaan sivulla: http://tdas.wordpress.com/2008/02/03/speed-up-grep/  . Saapa nähdä nopeutuuko.

« Viimeksi muokattu: 10.09.14 - klo:06.21 kirjoittanut petteriIII »

janne

  • Käyttäjä
  • Viestejä: 5150
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #146 : 11.06.13 - klo:22.50 »
Grep on kymmeniä kertoja hitaampi utf-8:lla kuin localella C. Enpä ole vielä kokeillut kun utf-8:lla nopeus on ollut toistaiseksi riittävä. Asiasta kerrotaan sivulla: http://tdas.wordpress.com/2008/02/03/speed-up-grep/  . Saapa nähdä nopeutuuko.

Asiasta kertova juttu on yli 5 vuotta vanha ja sillä sanotaan että "Future version of grep are planned to address this issue.". Grep on myös päivittynyt tuona viiden vuoden aikana useamman kerran, silloisesta versiosta 2.5.3, nykyisen Ubuntun mukana tulevaan versioon 2.14. Nopealla googletuksella selviää, että ongelma korjattiin versiossa 2.7.

Ei tuo tietenkään tarkoita, etteikö asiaa saisi huvikseen testailla.
Janne

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #147 : 12.06.13 - klo:12.10 »
Tattis vastauksesta, tuskinpa tuota kerkiää testaamaan ja kunnossahan se varmaan jo onkin; käytän grepiä aika paljon ja olen aina ihmetellyt kuinka niin nopeasti voi etsiä.
**
Harmittaa kuinka  arvostetuillakin nettisivuilla morkataan BASH:ia. Tekeytyvät BASH:ille "ystävällisiksi" mutta käyttävät vanhuuttaan kelvottomia toteutuksia ja yleistävät tulokset koskemaan koko BASHia. Menettäneet kehittymiskykynsä ja toimivat joo-joo-miehinä.   

Esimerkiksi BASH:in matemaattiset ominaisuudet - ei niitä oikeastaan ole joten kuinka niitä voi morkata? Morkkaajat eivät kykene edes bc:stä tekemään kunnollista. Kyvyttömät, eivät ne osaa tehdä muuta kuin repiä.

Matematiikkaa komentorivillä:
----------------------------------------
Jos kopioit kaikki funktiot foorumilta kirjoituksesta: http://forum.ubuntu-fi.org/index.php?topic=303.msg306401#msg306401             johonkin tiedostoon koneessasi ja annat käskyn:
gedit ~/.bashrc ja kirjoitat avautuvan tiedoston viimeiseksi riviksi: . polku_lataamaasi_tiedostoon    niin saat talletettuasi tiedoston ja bootattuasi päätteessä käyttöösi seuraavaa:

Voit kirjoittaa komentoriville minkätahansa laskun esimerkiksi: 2.5+2.5      tai: round[log[.11e2-2*sin+30]+ln[e^[round[16*[sin30*cos60]]]]]  ja enterin painamisen jälkeen kone kertoo oikean tuloksen; tässätapauksessa 5 eikä turhia perä-nollia esitetä vaikka onkin laskettu 60 desimaalia.
- komentorivin muu toiminta ei muutu ja käskyjä voi käyttää skripteissäkin.
- sallitut operaattorit: +, -, *, /, ^, %. Mikäli laskussa on operaattori / täytyy laskun eteen kirjoittaa sana: laske tai BASH tulkitsee laskun kansioksi. 
- parametrittömät funktiot : pi, e, #, asteet, radiaanit (lyhenne rad), round
- yksiparametriset funktiot: sin, cos, tan, atn, sqrt, log, ln, exp, abs, int, kertoma, kymppiin, kahteen (kantalukumuunnokset), desimaalit (lyhenne des)
- kaksiparametriset funktiot: power
- uusia funktioita voi tehdä; myös moni-parametrisia voi tehdä mutta mallia ei ole joten mukavaa pähkäilyä.
- kun laskuja suoritututtaa skripteistä käsin saa laskun tuloksen muuttujasta $(tulo); esimerkiksi: 2*2; sqrt$(tulo) 
- myös summaus-vähennystapa: +arvo tunnetaan. Tulkinta: lisää/vähennä siitä mikä edellisen laskun tulos oli.
- suluilla on niiden normaali merkitys. Suluiksi kelpaavat kuitenkin vain hakasulut.
- # on kommenttimerkki. Esimerkiksi ohjelmalle voidaan antaa laskettavaksi tiedoston. Tiedoston jokaisen rivin perään voi kirjoittaa kommentin. Kommentti alkaa merkillä #.
- power on desimaalisten eksponenttien laskemiseksi, esimerkiksi: power3^0.5

- desimaaleja on 60 ja trigonometria suoritetaan asteissa ellei toisin määrätä, esimerkikssi: laske des256radsin.5235988 . Määrättävä desimaalimäärä kuitenkin ilmoittaa bc:lle vain millätarkkuudella laskenta tulee vähitään suorittaa: jos jossakussa laskuun menevässä on enemmän desimaaleja niin desimaaliluku otetaan siitä. Asetukset säilyvät kunnes ne muutetaan noilla käskyillä tai bootataan.

- lukujen kokonaisosa huomioidaan kokoajan kokonaan onpa siinä kuinka monta numeroa hyvänsä. Ja mikäli ei erikseen määrätä niin ohjelman laskenta suoritetaan 66 desimaalin tarkkuudella ja tulostus tapahtuu toistaiseksi samalla tarkkuudella. Desimaalien lukumäärällä ei ole rajaa.

- tämä ohjelma käyttää laskuissaan matematiikka-ohjelmaa nimeltään bc. Matriisilaskuihin soveltuu paremmin awk joka osaa tekstinkäsittelyäkin.

- laskutusta voi ylläpitää tekstinkäsittely-järjestelmässä ja tulostaa laskutus-tiedostot laskuina. Vaikka tämä toimikin kokeissa niin kannattaa alkuun suhtautua erittäin varoen.

- siirrettäessä skripti toiseen koneeseen tai uuteen Linuxiin kannattaa skriptin toimivuus testata päässä-laskettavalx=2; laske $(echo [e^x-e^-x]/2 | sed "s/x/$x/g" | awk '{print $1}' )la mutta koneelle vaikeasti laskettavalla laskulla, esimerkiksi: round[log[.11e2-2*sin+30]+ln[e^[round[16*[sin30*cos60]]]]]  - tuloksen pitää olla 5 eikä siinä ei saa olla desimaaleja eikä laskuista saa tulla huomautuksia (warning).

- sevitys round:in toimintaan: laskettaessa jotakin jonka arvo on päättymätön numerosarja sattaa tuloksen viimeinen numero olla yksinkertaisissakin tapauksissa virheellinen yhdellä. Kun useammat pikkuvirheet kertautuvat saattaakin lopputuloksen useampikin viimeinen numero olla väärin. Käytettäessä laskemiseen bc:tä lasketaankin esimerkiksi kymmenen desimaalia enemmän kuin tarpeen olisi, hylätään yhdeksän viimeistä ja pyöristetään lopputulos kymmenennellä - toiminta on vähän hitaampaa mutta tulos varmasti oikea ja näyttävä - mitä siitä että se on matemaattisessa mielessä hölmöä.

- mikäli matematiikka suoritetaan eksponenttiluvuilla ei matematiikka voi olla tarkkaa. Tämä ei tarkoita ettei ohjelma saa hyväksyä eksponentti-muodossa olevia eikä sitäkään että ohjelma ei saisi esittää tuloksia eksponenttimuodossa. Tuntuu muuten siltä, että exel käyttää bc:tä - ja koska hyökkäys on paras puolustus niin Microsoft syyttää Linuxia.

- toiminta on hidasta niinkuin exel-tyyppisissä yleensäkin. Mutta tulokset ovat oikeita silloinkin kun muuten saa pelkkää virhettä. 

- lähes kaikilla funktioilla on monia mahdollisia laskutapoja elikä korvaus-funktioita: esimerkiksi sinhx voidaan laskea kaavasta: [e^x-e^-x]/2 . Tässä skriptissä merkintätapa on:
  x=2; laske $(echo [e^x-e^-x]/2 | sed "s/x/$x/g" | awk '{print $1}' )   ; kaikki muu on siis vakiota paitsi x=???.
  Sinh:in merkityksestä: hämähäkki kutoo verkkonsa aivoihinsa koodattujen sinh-taulukoiden mukaan, rakennuksien kestävyyslaskelmat tarvitsee sinh-funktioita - vaikka mitkä laskelmat tarvitsee myös sinh:iä.

- bc ei tunne desimaalisia eksponentteja. Niille ei taidakaan olla laskukaavaa, vaan ne täytyy laskea iteroimalla. Laskusta tuleekin vielä hitaampi kuin bc:llä normaalisti. Mutta lohdutusta saa siitä että rajoittamaton tarkkuuskin on tärkeämpää kuin normaalisti: tarkkoja desimaali-exponentteja on vaikea kehittää: exelistähänSuomalaiset sivut loistivat: ohjeet vain hieman epämääräiset, mutta esimerkiksi yksi arvovaltainen kansainvälinen sivu neuvoi tyyliin: miksi tehdä helposti kun voi tehdä vaikeastikin. niitä saa niinkuin taskukalkulaattoristakin, mutta tarkkuus on niillä huono.

Itseasiassa Linuxin työkalut myös matemaattisiin tehtäviin ovat erinomaiset. Mutta me kaikki olemme Wintoosan pilaamia ja yritykset toimia sillä tavalla kuin Wintoosa opettaa ovat epäonnistumaan tuomittuja. Lisäksi Linuxin merkintätavat ovat pitkiä ja ennenkaikkea täysin mahdottomia muistaa.
- esimerkiksi missä muussa kielessä voi tehdä matemaattisia vertailuja rajoittamattoman suurille, pienille ja pitkille numeroille? Vertailu täytyy ehdottomasti tehdä bc:n sisällä.
- bc: tä käytetäänkin lähes kaikkiin matemaattisiin ongelmiin; Linuxin omat matematiikka-käskyt opetellaan vain jotta saataisiin kielestä mielikuva.

- bc laskee ihan kiltisti myös negatiiviset desimaali-potenssit ilman kikkailua. Ongelmaksi kylläkin muodostui se ettei yksinkertaisillekaan laskuille riittänyt bc:n oletus-tarkkuus: 66-desimaalin tarkkuus. 

Tämä alkoi käydä mielenkiintoiseksi, sillä seuraava aste on enää toteutusta vaille ja sillä onnistuisi jo vähän edistyneempikin matikka - jaa, matriisi-matikkaa on jossakin. Mutta tarkoitus olisi siirtyä toteuttamaan kunnollisia kovalevy-funktioita: toimimattoman käyttöjärjestelmän päivitys ja muuta semmoista.

Kovalevy_funktiot onkin ensialkuun toteutettu itsenäisenä skriptinä jossa on myös versio hiiri_funktioista. Noviiseille tarkoitettu kovalevyn automaattinen korjaus ja boottauskykyiseksi tekeminen on jo tehty ja parhaillaan pähkäilen ammattikäyttöön tarkoitetun version kanssa.

- matematiikka toimii Trusty Tahrissa

btrfs toi taas kerran esiin tarpeen grubin editoimiseen:

Grubin "editointi" grub.cfg:ssä ehdotetulla tavalla
-----------------------------------------------------------------

Ubuntu 13.10:n grub on  kelvoton sillä varsinkin käytettäessä kokeellisia menetelmiä grubista pitää ehdottomasti näkyä mikä Ubuntun versio ja millä varusteilla on käytössä.
Samoin pankkiin ei pitäisi mennä saastuneella koneella, ja sen varmistamiseksi pankki-Ubuntun on syytä olla USB-tikulla joka on koneessa kiinni vain käytettäessä pankki-yhteyttä. (mikäli käyt internetissä niin koneesi voi olla saastunut. Pankki-sivuilla käynti on varsin turvallista.)
Myöskin käsiteltäessä sellaista jonka sekoittaminen mukuloiden toimesta on syytä estää täytyy tehdä sille tehtävälle oma ubuntu ja suojata grubin se kohta omalla salasanallaan jotta sitä ei voisi muuttaa.
 
- painotan siis: tämä on kehittäjien suosittelema keino, eikä tässä editoida grub.cfg:tä vaan sen aputiedostoa.
- Ubuntun kehittäjät tarjoavat tällaisen "staattisen valikon" tekemiseksi monia helpotuksia - esimerkiksi kuinka staattinen valikko saadaan ottamaan huomioon kerneleiden muuttumiseen päivitettäessä..
- tämä editoitu grub säilyy useimmiten myös asennettaessa uusi käyttöjärjestelmä. Jos asennetaan Windows niin alkulataaja täytyy omia takaisin. 
- koodi on sivulla: http://forum.ubuntu-fi.org/index.php?topic=30413.0
**
Jonkunsortin käsky kerrallaan askellus BASH-skripteille:
Tarkistettavan kohdan eteen kirjoitetaan koodiin rivi : set -x; trap "echo paina return;read x" DEBUG
Tarkistettanan kohdan perään kirjoitetaan koodiin rivi: set +x; trap "" DEBUG
- voihan siihen lisätä sillähetkellä tärkeiden muuttujien tulostusta ja sensemmoista.
- tämä trace-hommahan on parempi kuin muilla kielillä. Näennäisesti se on susi sillä kukaan ei ole vaivautunut selvittämään sitä vaan tiedot löytyvät vain man-sivujen sokkeloista. Ja tällähetkellä minä en jaksa hommaa selvittää.

 

 


« Viimeksi muokattu: 06.11.14 - klo:20.42 kirjoittanut petteriIII »

ajaaskel

  • Palvelimen ylläpitäjä
  • Käyttäjä
  • Viestejä: 3401
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #148 : 23.01.14 - klo:23.12 »
bash muuttujat ja taulukkotyyppisyys... kuiva aihe ?


Johdanto

Ehkä pieni kertaus ensin.  Ehdotan että avaat päätteen ja kokeilet siinä --- vaikka uteliaisuudesta.

Kaikki bash muuttujat ovat pohjimmiltaan taulukoita olkoonkin että sitä ei usein huomaa.  Muuttujaa ei määritellä erikseen mitenkään vaan sitä vain aletaan käyttää antamalla sille arvo jollakin tavalla jolloin muuttujan merkitys "kiinnittyy" samalla.  Riippuen miten annat arvon muuttujalle on tulos ja merkitys aivan erilainen.  Annetaan kokeeksi arvoja kahdella eri tavalla:

Koodia: [Valitse]
ekalista="kissa koira papukaija"
Koodia: [Valitse]
tokalista=(kissa koira papukaija)
Kuten tuttua "echo" komennolla voi näyttää muuttujan sisällön mutta silloin kun muuttujan sisältöä udellaan siihen laitetaan eteen dollarimerkki.  Katsotaanpa:

Koodia: [Valitse]
echo $ekalista
kissa koira papukaija

Koodia: [Valitse]
echo $tokalista
kissa
No minnekäs ne loput hävisivät tokalista: sta ?

Ei minnekään.  Ne menivät vain eri "laatikoihin" eli hienommin sanottuna kenttiin tuossa muuttujassa.  Voit kuvitella sekä muuttujaa "ekalista" että "tokalista"  lokerikkona jossa on vasemmalta oikealle numeroituja paikkoja.  Itse aloittaisit ehkä numeroinnin ykkösestä mutta näissä numerointi (hienommin sanottuna indeksi) alkaa nollasta.  Paikkanumerot juoksevat siis 0, 1, 2, 3,...    Yksittäisen paikan sisältöä voit kysellä antamalla sen numeron, katsotaanpa ensimmäisen paikan sisältö (jonka indeksi siis on nolla):

Koodia: [Valitse]
echo ${ekalista[0]}  
kissa koira papukaija
 
Koodia: [Valitse]
echo ${tokalista[0]}
kissa

Kurkitaan pidemmälle tuota tokalistaa:

Koodia: [Valitse]
echo ${ekalista[1]}
koira
Koodia: [Valitse]
echo ${ekalista[2]}
papukaija

Ekalistan tapauksessa nuo menivät kaikki yhdessä siihen ekaan laatikkoon jonka indeksi on nolla.
Tokalistan tapauksessa kukin meni omaan laatikkoonsa eli täytettiin paikat järjestyksessä 0, 1, 2.

Jos ihmettelet mitä niissä ekalistan "lopuissa" laatikoissa on niin ei mitään.  Kokeile itse:

Koodia: [Valitse]
echo ${ekalista[1]}
Koodia: [Valitse]
echo ${ekalista[2]}
Jos paikkanumeroa eli indeksiä ei anneta niin silloin kyseessä on vain se ensimmäinen paikka jonka indeksi siis on nolla.

Arvaan seuraavan ihmettelyn aiheen:  Mitenkäs sitten tulostan yhdellä kertaa kaikki laatikot tuosta tokalistasta ?
Tuohon tarkoitukseen on käytettävissä tähti "*" eli:

Koodia: [Valitse]
echo ${tokalista[*]}
kissa koira papukaija

Tuo tähti tarkoittaa tässä "kaikki".   Myös sähköpostiosoitteista tuttu "@" merkki tekee saman tässä yhteydessä.

Koodia: [Valitse]
echo ${ekalista[@]}
kissa koira papukaija

Toivottavasti uteliaisuutesi heräsi sillä mielenkiintoiset asiat oikeastaan alkavat tästä !


Ominaisuudet ja muunnokset

Molempia datamuotoja käytetään riippuen tilanteesta.  Joskus on kätevää että kukin olio on omassa laatikossaan jolloin ohjelmassa voi käydä laatikoita eli indeksejä läpi järjestyksessä vaikka "for-do-done" tai "while-do-done" komennolla.  Joskus taasen on kätevää saada yhdellä kertaa kaikki yhdestä indeksistä.

Merkkijonoille (joita nuo "kissa" "koira" ja "papukaija" ovat) samoin kuin koko "laatikostolle" voi tehdä suuruustarkastuksen.  Katsotaanpa mitä numeroita saadaan muuttujista "ekalista" ja "tokalista":

Koodia: [Valitse]
echo ${#ekalista[*]}
1

Koodia: [Valitse]
echo ${#tokalista[*]}
3

Saimme ilmiselvästi kenttien lukumäärän muuttujissa ekalista ja tokalista kuten pitääkin. Meitä voisi kiinnostaa myös minkä pituinen merkkijono on kussakin laatikossa.  bash ymmärtää kysymyksemme kun kerromme sille indeksin:

Koodia: [Valitse]
echo ${#ekalista[0]}
21

Tuo pitää paikkansa sillä välilyönti vie myös aina yhden merkkipaikan, kaikki lemmikithän olivat tuolla rinnakkain erotettuna yhdellä välilyönnillä: "kissa koira papukaija".  Tuon lokeron sisällä emme pysty indeksillä osoittamaan erikseen yksittäisiä lemmikkejä eli jos tarvitsemme sitä niin tulee käyttää tuota toista vaihtoehtoa (kukin lemmikki omaan soluunsa = tokalista).  

echo ${#tokalista[0]}
5

echo ${#tokalista[1]}
5

echo ${#tokalista[2]}
9

Näin saimme kustakin solusta siellä majailevan merkkijonon pituuden.

Voimme myös tallettaa mitä haluamme yksittäiseen soluun, muutetaanpas solu nolla muuttujassa tokalista niin että laitamme ylimääräisen välilyönnin kissan alkuun ja loppuun:

Koodia: [Valitse]
tokalista[0]=" kissa "
Tarkastetaan merkkijonon pituus sen jälkeen:

Koodia: [Valitse]
echo ${#tokalista[0]}
7

Tallessa ovat sekä kissa että välilyönnit sen kahta puolta.

Olenko sitten sidottu siihen kun tein "yksi-indeksisesti" tai "moni-indeksisesti" muuttujan alkuaan ?
Bash on ratkaissut muunnoksen muodosta toiseen hyvin yksinkertaisesti.
Jos muistat tuolta aivan laatikkoleikin alusta niin tavalliset sulut oli se taikasana joka sai aikaan sijoituksen monisoluisesti, kukin olio laitettiin omaan soluunsa eli laatikkoonsa.   Muunnoksen

kaikki yhdessä solussa  ------> kukin omaan soluun

voi tehdä helposti.  Otetaanpa tuo "ekalista"  missä meillä on "kissa koira papukaija" vieri vieressä mutta kaikki samassa solussa (eli indeksi nollan solu)  ja tipautetaan sisältö sieltä uuteen laatikkoon, olkoon nimeltään vaikka "uusilista" tuo muuttuja:

Koodia: [Valitse]
uusilista=(${ekalista[*]})
Jos nyt tarkastamme kuten jo edellä on kerrottu kustakin solusta niin huomaamme että kissa, koira ja papukaija ovat saaneet kukin oman solunsa tuossa uudessa muuttujassa eli löytyvät indekseistä 0, 1 ja 2:

Koodia: [Valitse]
echo ${#uusilista[*]}
3

Koodia: [Valitse]
echo ${uusilista[2]}
papukaija

Huomautus kokeneille lukijoille:  Tuo muunnos on riippuvainen asiasta nimeltään "IFS" jonka tulee olla vakioasetuksissaan.  Jos olet saanut sen muuksi niin sen saa palautettua oletusarvoihinsa komennolla
Koodia: [Valitse]
IFS=$' \t\n'IFS arvon säätely ohjelmassa on tarpeen joissakin erityistilanteissa, ei siitä sen enempää tässä.

Toiseen suuntaan muunnos on hyvin samanlainen, huomaa että sulut puuttuvat:

Koodia: [Valitse]
yksisoluinen=${uusilista[*]}

Bash: in muuttujat ovat aika käteviä "automaattisuutensa" vuoksi, ei tarvitse ihmeemmin miettiä datatyyppejä vaan alat vain käyttää muuttujaa. Kaikki muuttujat ovat yksiulotteisia taulukoita ja jos et käytä taulukkoindeksiä niin se on sama asia kuin että indeksi nolla on käytössä (ilman että sitä erikseen on laitettu näkyviin).
Tehdäänpä pieni koe havainnollistamaan mitä tapahtuu indeksin kanssa ja ilman:

Koodia: [Valitse]
lemmikki[0]=kissa
lemmikki[1]=koira
lemmikki[2]=papukaija

Tuo tekee 3 soluisen muuttujan jonka nimi on "lemmikki".  Tarkastetaanpa koko lemmikki eli

Koodia: [Valitse]
echo ${lemmikki[*]}
kissa koira papukaija

Totuuden paikka:  Muutetaan muuttujan "lemmikki" sisältöä niin että emme kerrokaan indeksiä:

Koodia: [Valitse]
lemmikki=marsu
Tarkastetaan:

Koodia: [Valitse]
echo ${lemmikki[*]}
marsu koira papukaija

eli muutos kohdistuu indeksiin nolla jos et kerro indeksiä.

« Viimeksi muokattu: 26.01.14 - klo:14.11 kirjoittanut ajaaskel »
Autamme ilolla ja ilmaiseksi omalla ajallamme.  Ethän vaadi, uhoa tai isottele näin saamasi palvelun johdosta.

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #149 : 03.03.14 - klo:17.12 »
bash muuttujat ja taulukkotyyppisyys

Kiitosta taas kertaalleen ! Kamalan iso homma tämmöisten tekemisessä on mutta on ne sitten hyödyllisiäkin.
**
Kyllä BASH-rintamalla tapahtuu kokoajan vieläkin, sillä BASH4.3 tuli äskettäin. Usoitteessa: http://www.tldp.org/LDP/abs/html/ on sen ohjekirja

Jossain vaiheessa oman koneen suojaamisesta tulee tärkeää. Eihän sitä tiedä onko BASH oikea
työkalu tietoturvan parantamiseen - tai siis BASH ei varmasti paranna mitään vaan parantaminen tehdään säätämällä Linuxia ja käyttämällä ulkoisia ohjelmia. Lisäksi välttämätön lisä on monimuotoisuus - ja silloin BASH loistaa sillä jokainen osaa tehdä jotakin käyttämällä BASHia.
**
Kyllä tällä BASH:illa saa tuloksia nopeastikin jos osaa käskeä. Minä en kylläkään osaa muuten kuin sattumalta. Esimerkiksi BASH osaa laskea 2500 kertoman noin 0.1 sekunnissa; kaikki sen 7000 numeroa jotka kaikki taitavat myös olla oikein.
Eihän laskukone ole BASH vaan bc - mutta BASH johtaa orkesteria ja yksinään bc ei toimisi sekään.
Tuommoisilla laskuilla on muuten merkitystä: joissain laskuissa on lopputulos pienehkö mutta laskujen väliarvot niin suuria ettei niihin pysty oikein mikään ja syntyvät pyöristysvirheet ovat suurempia kuin lopputulos.
**
Lasku "ln e" toimi aina vain yhden kerran ja toisintakerroilla ei tulostanut mitään; ei tosin päätynyt virheeseenkään. Kunnes lisäsin laskurutiinin loppuun: bash --login .
**
Matematiikkaohjelmaa ei käytännössä tarvitse kutsua vaan pääte toimii automaattisesti myös kalkulaattorina vaikka päätteen vanhat ominaisuudet säilyvätkin: senkun kirjoitat päätteeseen 1+1 niin painettuasi enteriä tulee vastaus: 2. Samoin voit skripteissäsi käytää matematiikkaa. Kaikki perus-merkintätavat ja -laskutoimitukset tunnetaan, siis vaikka tuon testilaskun: round[log[.11e2-2*sin+30]+ln[e^[round[16*[sin30*cos60]]]]] voi laittaa skriptiinsä ja vastaus: 5 tulee hetkenkuluttua. Eikä skriptiäsi tarvitse muuten muokata mitenkään.

Sieluna tässä on linuksin oma bc. Muuten "rajoittamaton tarkkuus" ei ole markkinointihöpinää. Mutta se on kylläkin tosi että se vaatii hieman tukea BASH:ilta.

Tietenkään tätä matematiikkaohjelmaa ei "kannata" käyttää sillä se on todella hidas, se tuntee vain yksinkertaisia laskuja ja sillä on omituisia ominaisuuksia paljon. Mutta sen arvo onkin siinä että se on itsetehty. Ja tietenkään tämä minun tekemäni ei ole sinun itsesi tekemä. Mutta tämä skripti osoittaa mitkä mahdollisuudet ainakin löytyvät ja alkuun on silloin helppo lähteä kun tietää että homma onnistuu vaikka työtä siinä voikin olla. Sinä voit tehdä skriptin jolla on paljon paremmat ominaisuudet ja nopeudellehan ei kattoa olekaan.

Esimerkiksi olisi varmaan kivaa käyttää jotain parhaista matematiikka-ohjelmista tämän orjana jolloin käytöstä saisi niin yksinkertaista kuin haluja-ja-kykyjä piisaa.
**
Uusien kykyjen lisääminen on helppoa, ja jostain ihmeellisestä syystä tämä itsetehty matikkaohjelma pystyy opettamaan minullekin matikkaa. Nyt lisäsin kyvyn seuraavankaltaisiin laskuihin: sin e^4
Lähes automaattisesti mukaan tulivat myös kantalukumuunnokset tyyppiä: kahteen e
**
Taas kertaalleen skriptiini oli tullut kontrollimerkkejä. Vaikka teen kehitettävästä skriptistä back-up:in aamuin-päivin-illoin niin nuo kontrollimerkit pilasivat jokaisen back-upinkin jonka latasin ja töistäni kerkisi mennä pilalle monen kuukauden työt ja pääsin takaisin toimintaan vasta kun latasin heti boottauksen jälkeen tuon parikuukautta sitten tehdyn skriptin ja hylkäsin kaikki sen jälkeiset skriptit.
« Viimeksi muokattu: 07.05.14 - klo:05.44 kirjoittanut petteriIII »

nm

  • Käyttäjä
  • Viestejä: 16425
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #150 : 07.05.14 - klo:15.28 »
Taas kertaalleen skriptiini oli tullut kontrollimerkkejä. Vaikka teen kehitettävästä skriptistä back-up:in aamuin-päivin-illoin niin nuo kontrollimerkit pilasivat jokaisen back-upinkin jonka latasin ja töistäni kerkisi mennä pilalle monen kuukauden työt ja pääsin takaisin toimintaan vasta kun latasin heti boottauksen jälkeen tuon parikuukautta sitten tehdyn skriptin ja hylkäsin kaikki sen jälkeiset skriptit.

Koodiin eksyneet väärät merkit saa kyllä poistettua vaikka tr-ohjelmalla. Laita joku vioittunut esimerkkitiedosto tänne niin voin vilkaista.

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #151 : 07.05.14 - klo:18.28 »
Koodia on liikaa jotta sen saisi laitettua foorumille - koetan kokoajan supistaa mutta hidasta tuntuu olevan. Ohjelman kokeileminen onnistuu kuitenkin helposti jahka saan koodia supistettua tarpeeksi. Lisään silloin ohjeet.
Toimiva versio kyllä on. Ohjelman logiikka on erittäin omituinen sillä pääohjelmana toimii terminal-ohjelma ja se kutsuu koodissa esitettyjä funktioita. Toiminta kalkulaattorina on vielä omituisempi, sillä kun terminaalin riville kirjoittaa jotakin jota ei vastaa yksikään funktio niin sen aiheuttama virhe aiheuttaa funktion command_not_found_handle kutsumisen. Funktio command_not_found_handle puolestaa kutsuu funktiota laske joka puolestaan kutsuu tarpeellisina pitämiään toisia funktioita. Tämän ohjelman tekeminen oli liian vaativaa minun ikäiselleni: työskentelyni oli liian hidasta joten työpäivistä tuli liian pitkät.

Ja kyllä tuota tr-käskyäkin on käytetty niinkuin käskyä od ja ohjelmaa bless - se kyllä täytyy tunnustaa että apu olisi tarpeen jotta saisi sovellettua käskyjä oikein. Sekin on epäselvää missä muuallakin sitä apua tarvitsisi, sillä vaikka puhunkin kontrollimerkeistä niin tuntuu siltä että niitä näkymättömiä merkkejä on runsaasti muitakin - ja esimerkiksi ainakin väri- ja kursori-kikkailu toimii kontrollimerkeillä joten niiden poistaminenkin on joskus vahingollista.

Koko konntrollimerkki-rumba olisi helppoa josvain gedit-ohjelma näyttäisi ne. Mutta en ole löytänyt siihen mitään konstia - netistäkään en ole löytänyt mitään. Kun nimittäin löytää rivin jossa niitä kontrollimerkkejä on niin senkuvaan pyyhkii rivin pois ja kirjoittaa uudestaan varoen hipaisemastakaan mitään kummallista nappia tai kosketuslevyä.

nm

  • Käyttäjä
  • Viestejä: 16425
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #152 : 07.05.14 - klo:18.44 »
esimerkiksi ainakin väri- ja kursori-kikkailu toimii kontrollimerkeillä joten niiden poistaminenkin on joskus vahingollista.

Näiden pitäisi kuitenkin olla koodissa escape-koodeina ascii-tekstinä, eikä raakoina kontrollimerkkeinä.

Koko konntrollimerkki-rumba olisi helppoa josvain gedit-ohjelma näyttäisi ne.

Heksaeditori on tähän oikea työkalu. Esimerkiksi Bless.

petteriIII

  • Käyttäjä
  • Viestejä: 693
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #153 : 12.05.14 - klo:06.25 »
Perus-matematiikkaa päätteelle opettava skripti mahtuu nyttemmin foorumille hyvin ja toimiikin kelvollisesti - sen lisäkehittäminen on mukavaa vaikka eihän koko skriptillä ole mitään käytännön merkitystä. Mutta en sitä ole tuon merkityksellisyyden takia tehnytkään vaikka sen rajoittamaton tarkkuus onkin mielenkiintoinen.

Sikälikin skripti on mielenkiintoinen että sen ominaisuudet olisivat olleet toteutettavissa jo kolmekymmentä vuotta sitten jolloin BASH jo menetti nopeasti merkitystään. Sekin mielenkiintoinen seikka selvisi skriptiä tehdessäni että vastaavankaltaisia skriptejä on jo ollutkin, mutta niiden koodia ei ole levitetty.

Sekin kummallisuus ilmeni että vastaavankaltaisia virheen-käsittelyyn soveltuvia skriptejä on ollut: ajattelepa että BASH:issa olisi jo valmiina erinomainen virheistä kertova rutiini !

Skriptin koodi on paikassa: http://forum.ubuntu-fi.org/index.php?topic=303.msg306401#msg306401
« Viimeksi muokattu: 14.06.14 - klo:17.13 kirjoittanut petteriIII »

nm

  • Käyttäjä
  • Viestejä: 16425
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #154 : 12.05.14 - klo:11.17 »
Vihdoin sain perus-matematiikan lisäävän skriptin supistettua tarpeeksi jotta se mahtuu foorumille. Siis matematiikkaa voit käyttää skripteissäsikin kunhan lisäät matematiikkarutiinit käyttöön ottavan käskyn. Pitänee aikanaan lisätä matriiseja käsitteleviä käskyjä, mutta ne ei vielä mahdu mukaan.

Toiminta: lataa koodi verkkosivulta http://forum.ubuntu-fi.org/index.php?topic=303.msg306401#msg306401

Koodi ja tämän keskustelun viimeiset viestit maaliskuulta lähtien kuuluisivat varmaan jonkin oman aiheen alle. Laita skripti viestiin liitetiedostoksi (Lisätoiminnot->Liite viestin kirjoituksen yhteydessä). Esimerkiksi .sh-tiedostopääte on sallittu, joten tiedoston nimeksi käy vaikkapa laskin.sh). Maksimikoko on 768 kB / liitetiedosto.

Vaihtoehtoisesti voit ladata tiedostot Dropboxiin tai johonkin muuhun pilvipalveluun. Ubuntuun saa Dropbox-asiakasohjelman, joka synkronoi koneellasi olevan hakemiston automaattisesti ja välittömästi verkkoon ja muille koneille, joilla on vastaava asiakasohjelma. Tätä voi hyödyntää sekä julkaisuun että omien tiedostojen varmuuskopiointiin. Nämä kannattaa tosin pitää erillään, eli julkaiset vain ajoittain toimivia versioita.

Seuraava askel onkin sitten versionhallinta gitillä, jolloin julkaisu onnistuu GitHubin kautta.
« Viimeksi muokattu: 12.05.14 - klo:11.20 kirjoittanut nm »

Whig

  • Käyttäjä
  • Viestejä: 356
  • puppu-generaattori
    • Profiili
    • localhost
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #155 : 21.07.14 - klo:07.55 »
Yritän scriptissä laskea mm prosentteja mutta saan tulokset jotka ovat yhteenlaskettuna yleensä vain 99%:a.
Eli on kolme arvoa joista lasken prosentit 100*arvo1/kaikki ja 100*arvo2/kaikki ja 100*arvo3/kaikki ja näiden tulokset sitten plussailen yhteen. Epäilen, että itse laskut menevät oikein mutta scripti pyöristää arvoista desimaalit pois (arvo1,arvo2,arvo3 ovat aina lukuja ilman desimaaleja).
Mitenköhän saisi tuohon myös desimaalit mukaan? Nyt arvo1 on 38 ja kaikki on 1866 josta saan laskimella laskettuna 2,036 % mutta scripti näyttää 2% ja ilmeisesti kaikissa prosentteissa samanlaista heittoa jolloin lopputulos on melkein oikein.
arvo3 on 428 ja yhteensä yhä 1866 ja tästä laskettuna laskimella 22,93% mutta scriptini näyttää 22% :-/

Edit:
Niin juu ja prosentit lasken näin: luku=$((100*$ARVO1/$KAIKKI))
« Viimeksi muokattu: 21.07.14 - klo:08.00 kirjoittanut Whig »

nm

  • Käyttäjä
  • Viestejä: 16425
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #156 : 21.07.14 - klo:09.56 »
arvo3 on 428 ja yhteensä yhä 1866 ja tästä laskettuna laskimella 22,93% mutta scriptini näyttää 22% :-/

Edit:
Niin juu ja prosentit lasken näin: luku=$((100*$ARVO1/$KAIKKI))

Bash tukee vain kokonaislukulaskentaa, eli mitään desimaaliosia ei saa ulos, eikä niitä voi myöskään syöttää sisään. Jakolaskut pyöristyvät alaspäin, kuten esimerkistäsi nähdään.

Tarkempaa laskentaa voit tehdä esimerkiksi bc:n tai awk:n avulla.

bc:

Koodia: [Valitse]
luku=$(bc <<< "scale=4; 100*$ARVO/$KAIKKI")
Koodia: [Valitse]
ARVO=428 KAIKKI=1866 luku=$(bc <<< "scale=4; 100*$ARVO/$KAIKKI"); echo $luku
22.9367

awk:

Koodia: [Valitse]
luku=$(awk "BEGIN{printf \"%.4f\n\",100*$ARVO/$KAIKKI}")
Koodia: [Valitse]
ARVO=428 KAIKKI=1866 luku=$(awk "BEGIN{printf \"%.4f\n\",100*$ARVO/$KAIKKI}"); echo $luku
22.9368


bc:n ongelmana on tulosteen leikkautuminen, eli se ei pyöristä oikein. Lisäksi etunolla puuttuu tulosteesta, kun arvo on välillä (-1, 1):

Koodia: [Valitse]
ARVO=1 KAIKKI=1000 luku=$(bc <<< "scale=2; 100*$ARVO/$KAIKKI"); echo $luku
.10
« Viimeksi muokattu: 21.07.14 - klo:09.58 kirjoittanut nm »

Whig

  • Käyttäjä
  • Viestejä: 356
  • puppu-generaattori
    • Profiili
    • localhost
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #157 : 21.07.14 - klo:10.26 »
Bash tukee vain kokonaislukulaskentaa, eli mitään desimaaliosia ei saa ulos, eikä niitä voi myöskään syöttää sisään. Jakolaskut pyöristyvät alaspäin, kuten esimerkistäsi nähdään.

Tarkempaa laskentaa voit tehdä esimerkiksi bc:n tai awk:n avulla.

bc:

Koodia: [Valitse]
luku=$(bc <<< "scale=4; 100*$ARVO/$KAIKKI")

Kiitän. Laitoin tällä (scale=2:lla tosin) ja jo näytti paremmalta.

Lainaus
bc:n ongelmana on tulosteen leikkautuminen, eli se ei pyöristä oikein. Lisäksi etunolla puuttuu tulosteesta, kun arvo on välillä (-1, 1):

Koodia: [Valitse]
ARVO=1 KAIKKI=1000 luku=$(bc <<< "scale=2; 100*$ARVO/$KAIKKI"); echo $luku
.10

Täytyy seurailla tilannetta tuleeko tästä ongelmaa pienin arvo luvulla tässätapauksessa voi olla 0 joten etunollasta ei varmaankaan tule ongelmaa mutta tuon pyöristyksen näkee sitten, kun saan tuon kunnolla testiin.

nm

  • Käyttäjä
  • Viestejä: 16425
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #158 : 21.07.14 - klo:11.21 »
Käyttäisin itse awk:ta, erityisesti jos viimeisellä desimaalilla on jotain merkitystä. Sen kanssa ei tule kumpaakaan ongelmaa. bc on hyödyllinen, jos laskutoimituksissa tarvitaan suurta tarkkuutta (enemmän kuin normaalien double-liukulukujen 15 numeroa).
« Viimeksi muokattu: 21.07.14 - klo:11.26 kirjoittanut nm »

rationaalinen

  • Käyttäjä
  • Viestejä: 67
    • Profiili
Vs: Ohjeita shell-skriptaukseen (bash)
« Vastaus #159 : 08.08.14 - klo:13.07 »
Tervehdys Ubuntu & shell skriptaus gurut!

Kiitän näin aluksi tämän alueen keskustelijoita hyvistä vinkeistä ja esimerkeistä joiden avulla olen kirjoittanut muutaman valokuvien ja videoiden käsittelyä automatisoivaa shell-skriptiä.

Kysymys:
Miten shell-scriptillä saisi välitettyä useamman argumentin komentorivi-ohjelmalle vaiheittain ja sitten suljettua ohjelman?
Esim. echo 1+2 | octave
käynnistää octave:n, palauttaa tuloksen ans = 3 ja sulkee automaattisesti octave:n.

Entä jos haluaisin octave:n laskevan kaksi operaatiota ja sulkeutuvan vasta sitten? Esim. 1+2 ja 2+3 ja sulkeutuvan vasta toisen operaation jälkeen. Esimerkkien lopputulokset tulostuisivat shell:iin "ans = 3" ja "ans = 5".

t. Rationaalinen