Institute of Computer Science
  1. Courses
  2. 2021/22 fall
  3. Operating Systems (LTAT.06.001)
ET
Log in

Operating Systems 2021/22 fall

  • Pealeht
  • Loengud
  • Praktikumid
  • Kodutööd

Skriptimine Linuxis

Praktikum annab ülevaate käsurea skriptide loomisest Linuxis. Tihti on keerulisemate käsurea toimingute jaoks palju mugavam teha ette valmis skriptid, mida saab tulevikus perioodiliselt kasutada.

Sissejuhatus

Skript on sisuliselt tekstifail, kus sees on käsud. Skriptide koostamisel tuleb kasutada tekstiredaktorit, valikuid on Linuxis mitmeid. Vali see redaktor, mis sulle enim meeldib, kuid soovitame installeerida Kate, kuna see teeb skriptide kirjutamise lihtsamaks.

  • sudo apt update
  • sudo apt install kate
  • Otsige programmide loendist installeeritud programm kate ja käivitage see.
  • Alternatiivsed terminalis töötavad editorid: nano, vim. Alternatiivne GUI editor: gedit.

Skriptide loomine ja käivitamine

Kui tahad skripti käivitada sarnaselt tavalise Linuxi programmiga, siis peab sellel olema korrektne päis (esimene faili rida) ning failile tuleb lisada käivitamisõigus. Skriptifaili päis määrab ära, millist käsureinterpretaatorit kasutatakse skripti käivitamisel.

  • Pannes skripti päiseks, ehk esimeseks reaks #!/bin/sh, määratakse skripti interpretaatoriks standardne POSIX-ühilduv käsuintepretaator (Bourne Shell).
    • Algselt kasutati Linuxis sh'na bash'i (Bourne-again shell), Ubuntus ning seega ka meie süsteemis on see alates versioonist 6.10 dash (Debian Almquist shell), mõnedes teistes süsteemides aga endiselt bash.
    • Soovitav on kasutada skriptide jaoks tavalist Bourne Shelli /bin/sh, kui ekstra muid laiendusi tarvis pole - niisugused skriptid on kasutatavad ka muudes Unixi baasil operatsioonisüsteemides, kus puudub /bin/bash. Bash on sobiv interaktiivseks tööks terminalis ning mõnikord skriptide loomisel (juhul, kui Bashi laiendusi väga vaja on).
  • Käsureaskriptide kokkuleppeline failide laiend on .sh, aga palju kasutatakse ka lihtsalt ilma laiendita failinimesid - oluline on, et fail oleks käivitatav.
  • Silumisvahendina on kasulik -x lipp sh käivitamisel, näiteks sh -x skriptinimi.sh või esimesel real #!/bin/sh -x - see näitab ridahaaval välja, mida täidetakse.

Ülesanne 1

  • Loo uus skriptifail esimene.sh, pane paika selle päis ning skripti sisuks lisa rida:
    • echo "Tere, tali!!"
    • echo on käsuinterpretaatori käsk, mis väljastab ekraanile (standardväljundisse) oma argumendid
  • Käivitamiseks on vajalik anda skriptile käivitamisõigus:
    • chmod 700 esimene.sh
  • Käivita skript käsurealt nii:
    • ./esimene.sh

Muutujad ja käsurea parameetrid

Skriptides on võimalik kasutada mitut erinevat tüüpi muutujaid:

  1. Protsessilt protsessile päranduvad keskkonnamuutujad
    • $PATH - kust otsida käivitatavaid programme, kui nende asukoht pole täisteega määratud
    • $USER - kasutajanimi
    • $PWD - protsessi hetkel aktiivne töökataloog
  2. Skripti sisendi muutujad, mille kaudu saab ligi skripti argumentidele ja muule skriptiga seotud informatsioonile
    • $0 - skripti nimi
    • $1 $2 .. $9 - skripti käsurea argumendid
    • $$ - käesoleva interpretaatori (shell'i) PID
  3. Skripti sisesed lokaalsed kasutaja poolt määratud muutujad
    • Muutuja väärtustamisel piisab vaid nime määramisest:
      • nimi=Juku (NB! Võrdusmärgi ees ja järel ei tohi olla tühikuid!)
    • Muutuja väärtuse kasutamisel tuleb nime ette panna $ märk:
      • echo $nimi
    • Kasutades ülakomasid (') teksti ümber, ei asendata seal sees muutujate väärtusi (ehk märk $ ei oma mõju, kui see on ülakomade vahel)
      • echo 'Ei asenda muutujat $1 tema väärtusega'
    • Kui aga kasutada juttumärke ("), toimub asendus ilusti.
      • echo "Asendatakse muutuja $1 tema väärtusega"

Ülesanne 2

  1. Skripti käivitamisel lisa argumendina oma nimi:
    • ./esimene.sh "Juku Mets"
  2. Pane skript väljastama tervitust argumendis nimetatud isikule.
    • Proovi, mis juhtub siis, kui argumendi määramisel jutumärke ei kasuta?

Interaktiivne sisend

Selleks, et küsida kasutaja käest täiendavat informatsiooni (näiteks failinime), saab kasutada read käsku nii:

echo "Sisesta väärtus:"
read sisse
echo "Sisestati: $sisse"

Ülesanne 3

  • Muuda oma esimene.sh skripti nii, et küsitakse kasutaja käest ükshaaval tema nimi, eriala ning matrikli number.
  • Sisestatud vastused tuleb väljastada ekraanile.

Juhtvood

Sarnaselt muudele programmeerimiskeeltele on võimalik skriptides kasutada erinevaid tingimusi ja juhtvoogusid.

IF-ELSE

Teistest programmeerimiskeeltest juba hästi tuntud IF-ELSE konstruktsioon:
NB! Pöörake tähelepanu [] sulgude juures enne ja pärast tühikute kasutamisele!

#!/bin/sh
a=$1
if [ $a -lt 1000 ]
then
     echo "Sisestatud arv on vaiksem kui 1000"
elif [ $a -ge 1000 -a $a -le 5000 ]
then
     echo "Sisestatud arv on vahemikus 1000 kuni 5000"
else
     echo "Sisestatud arv on suurem kui 5000"
fi
  • Operaatorid teksti (stringide - kõik muutujad on siin stringitüüpi) võrdlemisel:
    • = - võrdne
    • != - mittevõrdne
    • -z - On tühi
    • -n - Ei ole tühi
  • Operaatorid arvude võrdlemisel (stringide intepreteerimine tekstina esitatud arvudena):
    • -eq - võrdne (ingl. k. equal)
    • -ne - mittevõrdne (ingl. k. not equal)
    • -lt - väiksem (ingl. k. less than)
    • -le - väiksem või võrdne (ingl. k. less or equal)
    • -gt - suurem (ingl. k. greater than)
    • -ge - suurem või võrdne (ingl. k. greater or equal)
  • Ning loogikaavaldised:
    • -a (AND) nõuab mõlema tingimuse samaaegset täidetust
    • -o (OR) väljendab, et täidetud võib olla üks või teine või mõlemad.
    • ! (NOT) alustades tingimust hüüumärgiga, märgitakse eitust

While

While tsükli sisu korratakse seni, kuni tingimus on tõene. Näites sooritatakse järgnev sisu, kuni muutuja $a on väiksem kümnest:

#!/bin/sh
a=0
while [ $a -lt 10 ]
do
     echo $a
     a=$(($a+1))
done

For

For kordus on kasulik mingi nimekirja või listi läbi vaatamiseks:

#!/bin/sh
a="Martin Janar Tiit Juku"
for i in $a
do
    echo "$i"
done

NB! Kui tegemist on teksti sisaldavate muutujatega, siis on soovitav muutuja kasutamisel ümbritseda see " märkidega nii: echo "$i"

Ülesanne 4

  • Loo skript, mis nimetab kõik etteantud kaustas asuvad .txt laiendiga failid ümber .csv laiendiga failideks.
  • Seda ja järgnevaid skripte soovitame käivitada bashis (faili alguses rida #!/bin/bash), sest bashi laiendused teevad tekstiasendusi lihtsamaks.
    • Vaata tsükli abil läbi aktiivses kataloogis leiduvad failid.
      • Mingi käsu väljundi saab avaldisse asendada, ümbritsedes selle $(...) konstruktsiooniga. Näiteks käsu ls puhul: valjund=$(ls)
      • Sarnsaselt saab käsu väljundit läbi vaadata ka for tsüklis (for i in $(ls))
    • Kontrolli laiendit. if [ ${i##*.} = txt ]; then
      • Siin ${muutuja_nimi_ilma_dollarita##tekst} asendab pikima võimaliku prefiksi (kõik enne "." oleva teksti) tühja stringiga, seejärel kontrollime (=) kas allesjäänud osa võrdub soovitud laiendiga (txt). Niisuguseid teisendusi on veel, vt. man sh seest "Parameter Expansion" jaotist.
    • Kui kontroll läheb läbi, nimeta fail ümber.
      • Ümber saab faili nimetada mv abil
      • Nime saab asendada näiteks sed abil:
        echo "failinimi.txt" | sed -e s/asendatav_text/asendus_text/ ja selle programmi tulemus tuleks siis $(...) konstruktsiooni abil mv argumendi sisse asendada.
      • Võime kasutada ka **Parameter Expansion** funktsionaalsust ${muudetav_text/mida_muudame/milleks_muudame} rohkem infot siin
$ fail=failinimi.txt; mv $fail $(echo $fail | sed -e s/.txt/.csv/g)
$ fail=failinimi.txt;laiend1=.txt;laiend2=.csv; mv $fail ${fail/$laiend1/$laiend2}
  • Täienda programmi nii, et nii muudetav kui ka asendatav faili laiend loetaks sisse argumendina kasutaja käest.

Ülesanne 5

  1. Loo skript, mis võtab argumendiks protsessi nime ning väljastab selle process ID ja nime.
    • Otsi protsessi käsu ps -A väljundist.
    • Otsida võid kohe ps-A väljundis käsu grep abil või siis iga rea puhul võrrelda kas programmi nimi on õige.
    • Vaata kõik käsu väljundi read ükshaaval läbi. Seda on võimalik teha näiteks nii:
#!/bin/bash
IFS=$'\n'
# Eraldaja ümber muutmine tühikust reavahetuseks

for line in $(ls)
do
     echo "$line"
done
  • Selles näites muudetakse shelli muutuja IFS väärtus ajutiselt ümber reavahetuseks, et saaks käsu väljundit läbi vaadata ühe rea kaupa.
  • Vihjed: Väljasta protsessi nimi ja PID iga leitud protsessi kohta.
    • Selleks, et leida esimest "sõna" tühikutega eraldatud "lauses" on võimalik kasutada echo $line | cut -d ' ' -f1 kus -fn määrab ära mitmes sõna ning -d määrab ära eraldaja.
    • Probleeme tekib siis, kui eraldajaks on rohkem kui üks tühik!
      • Selle vältimiseks on võimalik lisada echo ja cut vahele käsk: tr -s ' ', mis eemaldab korduvad tühikud.
    • Probleeme tekitab (ajab tulbad nihkesse) ka esimene tühik, mis osadel ridadel on ja teistel pole.
      • Selle probleemi saab kergesti lahendada lisades kõigile ridade algusesse ühe tühiku lisaks, ning siis kõik korduvad tühikud ära eemaldada (näiteks echo " "$line | tr -s ' ' | cut -d ' ' -f2 kus " "$line lisab tühiku rea ette.

Funktsioonid

Tihtiesinevaid tegevusi skriptides on mõistlik kirjeldada funktsioonina, mida saab hiljem mitmeid kordi välja kutsuda.

  • Funktsiooni saab sama skripti piires välja kutsuda nagu teist skripti või Linuxi käsku.
  • Selleks, et funktsiooni (või ükskõik millise käsu) väljund avaldise sisse asendataks (näiteks muutuja väärtuse seadmisel), tuleb kasutada "`" märke või $() konstruktsiooni nii:
    • echo "Funktsioonid väärtustatakse nii: $(minu_funktsioon 3 4 5)"
    • Kasutage $(()) kui soovite, et teie kood lisaks muutuja asendustele arvutaks ka sulgude sees oleva tehte väärtuse (näites a=$(($1 + $2)), kusjuures siin $1 ja $2 on väljakutsumisel antud meetodi sisendparameetrid, mitte skripti käivitamisel sisestatud väärtused.)

Näiteks loome funktsiooni, mis arvutab summat:

#!/bin/bash
summa () {
  a=$(($1 + $2))
  echo  $a
}

a=$(summa 23 11) 
b=$(summa $a 1)
echo $b

Ülesanne 6

  1. Loo funktsioon astendamiseks, kasutades korrutamistehet.
    • Kasuta kas rekursiooni (9^5 == 9*(9^4))
    • Või näiteks WHILE/FOR tsüklit.
  2. Väljasta oma skriptis 9^5 väärtus, kasutades loodud funktsiooni

Viki

Oma viki leheküljele lisa:

  1. Kõigi siniste ülesannete (3-6) lahendamiseks loodud skripti(de) sisu.
    • Ei tohi olla ekraanivaatena lisatud.
    • Soovitame kasutada [@ ja @] koodi küljendamiseks vikis.
  2. Kõigi siniste ülesannete (3-6) lahendamiseks loodud skripti(de) väljundid.
    • Peavad olema ekraanivaatena lisatud.

Tulemuse esitamine

Kui teil on viki lehekülg valmis, siis lisage meile kommentaar (koos mingi tühja failiga).

10. Praktikum 10 - Skriptimine Linuxis
Solutions for this task can no longer be submitted.

(Tähtaeg 2 nädalat)

  • Institute of Computer Science
  • Faculty of Science and Technology
  • University of Tartu
In case of technical problems or questions write to:

Contact the course organizers with the organizational and course content questions.
The proprietary copyrights of educational materials belong to the University of Tartu. The use of educational materials is permitted for the purposes and under the conditions provided for in the copyright law for the free use of a work. When using educational materials, the user is obligated to give credit to the author of the educational materials.
The use of educational materials for other purposes is allowed only with the prior written consent of the University of Tartu.
Terms of use for the Courses environment