Göm menyn

TDP001 Handhavande av datormiljö

Terminalkommandon v38

Villkor

I Dash har vi if-satser. Här kommer definitionen enligt manualsidorna (för dash):
           if list
           then list
           [ elif list
           then    list ] ...
           [ else list ]
           fi
Som ni ser förekommer ordet list en del. Manualsidorna beskriver det som en sekvens av noll eller flera kommandon separerade med nyradstecken, semikolon eller &-tecken.

Ett kommando i terminalen returnerar 0 om det lyckades och något annat om något misslyckades. Villkoren anses alltså vara uppfyllda om deras resultat är 0.

Här kommer ett litet exempel:

    if grep -q 'body' fil.html
    then echo Valid
    else echo 'Wrong!'
    fi
Skriver ut Valid om html-filen innehåller texten body (inte så jätteavancerad kontroll kanske...), annars texten Wrong! Exakt samma exempel går att skriva på andra sätt också (semikolon och nyrad är ekvivalenta och det gör inget att ha för många):
   if grep -q 'body' fil.html; then echo "Valid"
   else 
   	echo "Wrong!"
   fi
Ofta används if-satser tillsammans med dubbla hakparenteser där följande kan kontrolleras (och många fler, se rubriken CONDITIONAL EXPRESSIONS i manualsidorna för bash):
   -f file       Sant om file är en vanlig fil
   -d file       Sant om file är en katalog
   -s file       Sant om filen file finns och har innehåll
   -r/-w/-x file Sant om file är läsbar/skrivbar/körbar
   -n string     Sant om string har en längd
   -z string     Sant om string är tom
   s1 = s2       Sant om strängarna s1 och s2 är lika
   s1 != s2      Sant om strängarna  s1 och s2 inte är lika
   s1 =~ r	 Sant om s1 matchar reguljära uttrycket r
   Jämförelse av tal (observera att omvandling från sträng sker):
     n1 operator n2   (operator är en av vanliga jämförelseoperatorerna)  
Exempel:
   if [[ -z $var ]]; then 
     echo "var är tom!"
   elif [[ $var = "Ja" ]]; then
     echo "var är Ja!"
   elif [[ $var < "5" ]]; then
     echo "var är mindre än 5"
   else
     echo "Okänt värde!"
   fi
Mellanslagen efter [[ och före ]] är ett krav. Det finns även en variant med enkla hakparenteser, denna variant är dock lite mer grundläggande. Om man vill kan man även göra lite mer matematiska beräkningar (går såklart även att göra utanför ett villkor). Det gör man inom $(( ... ))
   x="3"
   y=6
   echo $((x+y))
Som ni ser slipper vi använda $-tecknet för att komma åt variabler inom matteläget. Tänk dock på att matematikläget ger ett numeriskt värde som svar så det går inte helt att använda direkt i villkor: Om vi vill använda matematikläget i villkor utelämnar vi $-tecknet helt.
   if $((x+y < 10)); then echo "liten summa"; fi 
   bash: command not found: 1
   
   if ((x+y < 10)); then echo "Liten summa"; fi
x+y < 10
gav värdet sant som omvandlas till 1 och 1 är inte ett kommando som bash kan köra.

Upprepningar

Det finns två upprepningssatser i bash; while och for
    while list
    do list
    done
Behöver kanske inte diskuteras så mycket, den inre listan av kommandon körs så länge den övre är sann (returnerar 0)

Ett inbyggt kommando som kan vara bra att ha till while är read. read läser en rad från standard inmatningsström (STDIN) och lagrar den i en variabel. Använder man read i en loop läser vi en rad i taget likt python:

    emptyLines=0
    cat filname | while read line
    do 
      if [ -z $line ]
      then
        emptyLines=$((emptyLines+1))
        # eller ((emptyLines++))
      fi
    done

    echo "$emptyLines empty lines in file"
Här har vi for:
    for variable [ in [ word ... ] ]
    do list
    done
Här fungerar det också mycket likt python, for skapar en variabel och går igenom en lista av ord.
    $ for str in hej alla studenter; do echo $str; done
    hej
    alla
    studenter
Ett bra inbyggt kommando här är seq. seq är väldigt likt range i python:
    $ for i in $(seq 1 5); do echo $i; done
    1
    2
    3
    4
    5
En skillnad är dock att man kan öka med mer än ett men här anges ökningen mellan start- och slutvärde. Det har också möjlighet att stega med decimaler:
   $ for i in $(seq 2 -.2 1.3); do echo $i; done
   2,0
   1,8
   1,6
   1,4
Man kan även ange glob-mönster här:
   for f in ~/*.py; do echo $f; done
Här listar vi alla .py-filer i din hemkatalog
   
for f in ~/*.py; do mv $f ${f%.py}_bak.py; done
Här byter vi ut filnamet på samtliga .py-filer, exempelvis kommer a.py heta a_bak.py efter kommandot.

Sidansvarig: Pontus Haglund
Senast uppdaterad: 2020-08-18