Bruger man en række Bash-kommandoer ofte, kan man samle dem i et shellscript, som egentlig bare er et lille program, man kan køre. Lad os starte med at lave et super simpelt shellscript, for at se hvordan man gør:
claus@ClausDesktop:~/work$ cat shellscript.sh #!/bin/bash echo "Hello World!" claus@ClausDesktop:~/work$ chmod 755 shellscript.sh claus@ClausDesktop:~/work$ ./shellscript.sh Hello World!
Dette shellscript udskriver bare "Hello World!" vha. echo
-kommandoen, men bemærk den første linie i scriptet: #!/bin/bash
.
Denne linie bliver kaldt en shebang, og den fortæller bare at scriptet er et Bash-script; f.eks. kunne man også lave et Octave-shellscript ved at bruge en anden shebang (#!/usr/bin/env octave
).
I et shellscript kan man skrive Bash-kommandoer, men man kan også meget mere end det.
Variabler og Parametre
Et shellscript fungerer som et lille program, og ligesom med programmer kan man sende parametre til programmet når man kører det fra terminalen. Her er et eksempel:
claus@ClausDesktop:~/work$ cat shellscript.sh #!/bin/bash echo "Hello $1!" claus@ClausDesktop:~/work$ ./shellscript.sh Claus Hello Claus!
Man kan altså tilgå parametre med $1
, $2
, $3
, osv. og du kan se antallet af parametre i $#
.
Bemærk at parametrene er eksempler på variabler, som du måske kender fra andre programmeringssprog.
Man kan lave variabler i Bash ved at skrive NAVN=VÆRDI
, hvor NAVN er navnet på variablen, og VÆRDI er f.eks. et tal eller en tekststreng angivet med anførselstegn ("tekst"
).
Man kan så senere bruge variablen ved at skrive $NAVN
. Læg mærke til at parametrene derfor bare er variabler med navnene #
, 1
, 2
, osv.
Her er et eksempel mere, der også definerer nogle variabler:
#!/bin/bash FILEEXTENSION="txt" OUTPUTFILE="$1.$FILEEXTENSION" echo "Test!" > $OUTPUTFILE echo "En anden linie skrevet til filen!" >> $OUTPUTFILE echo "En tredje linie!" >> $OUTPUTFILE LINIER=`cat $OUTPUTFILE | wc -l` echo "Der blev skrevet $LINIER linier til filen $OUTPUTFILE!"
Definitionen af variablen LINIER
er lidt speciel - ved at skrive Bash-kommandoer mellem `
og `
kan du gemme resultatet af en Bash-kommando i en variabel (bemærk at du godt kan bruge piping med |
!).
Ellers bliver der bare defineret nogle variabler, og de bliver brugt ved at skrive $
foran navnet.
Hvis du kører scriptet skulle du gerne få følgende resultat:
claus@ClausDesktop:~/work$ ./shellscript.sh test Der blev skrevet 3 linier til filen test.txt! claus@ClausDesktop:~/work$ cat test.txt Test! En anden linie skrevet til filen! En tredje linie!
Betingelser
Hvad nu hvis dit script kræver f.eks. tre parametre, og brugeren kun indtaster to? Det kan du tjekke vha. en betingelse eller if
-sætning:
#!/bin/bash if [ $# -eq 3 ] then echo "Du har indtastet 3 parametre!" else echo "Du har indtastet $# parametre, men du skulle indtaste 3!" fi
Generelt kan du skrive if [ betingelse ] then ... fi
, hvor betingelse er et udsagn, som f.eks. at antallet af parametre skal være lig med (equal, -eq
) værdien 3, som i eksemplet ovenfor.
Du kan også bruge større end (greater than, -gt
) eller mindre end (less than, -lt
) i stedet for -eq
.
Hvis betingelsen er sand, køres kommandoerne mellem then
og fi
, mens de ignoreres hvis betingelsen er falsk.
Man kan desuden bruge else
(som i eksemplet ovenfor): hvis betingelsen er sand, køres koden mellem then
og else
,
og hvis betingelsen er falsk køres i stedet koden mellem else
og fi
.
Loops
Hvis du skal gentage nogle kommandoer flere gange, kan du bruge loops. Prøv selv dette eksempel af:
#!/bin/bash for i in 1 2 3 "Hund" "Kat" "Fisk" 42 do echo "i: $i" done for j in $(seq 1 10) do echo "j: $j" done
Når du bruger sådan et loop får du en variabel (her i
eller j
) som kun findes mellem do
og done
for det ene loop,
og som skifter værdi hver gang kommandoerne mellem do
og done
bliver kørt (indtil variablen har haft alle de forskellige værdier, der blev bedt om, dvs. 1, 2, 3, Hund, Kat, Fisk og 42 i første loop).
Her er et andet eksempel:
claus@ClausDesktop:~/work$ cat shellscript.sh #!/bin/bash for i in $(seq $1 $2) do echo "i: $i" done claus@ClausDesktop:~/work$ ./shellscript.sh 4 7 i: 4 i: 5 i: 6 i: 7
Aritmetik
Hvis du har brug for at lave en smule matematik - eller rettere aritmetik - kan du bl.a. gøre det vha. $
og dobbelt-paranteser: $(( ... ))
.
Her er et eksempel:
claus@ClausDesktop:~/work$ cat shellscript.sh #!/bin/bash RESULTAT=$(($1 + $2)) echo "$1 + $2 = $RESULTAT" claus@ClausDesktop:~/work$ ./shellscript.sh 4 7 4 + 7 = 11
Bemærk dog at du kun arbejder med heltal på denne måde. Hvis du i stedet skal bruge decimaltal er du nødt til at bruge programmer som f.eks. en Python-fortolker:
claus@ClausDesktop:~/work$ cat shellscript.sh #!/bin/bash RESULTAT=`python -c "print($1 + $2)"` echo "$1 + $2 = $RESULTAT" claus@ClausDesktop:~/work$ ./shellscript.sh 4.2 7.1 4.2 + 7.1 = 11.3
Heredoc
Nogle gange er Bash ikke nok, eller måske vil du bare gerne bruge f.eks. Python eller Octave til nogle beregninger, plotting af data, eller lignende. Her kan du lave en ekstra script-fil, f.eks. plot_data.m, som du kan køre fra dit shellscript (hvis f.eks. dit shellscript forbereder en fil med data der skal plottes). Alternativt kan du skrive dit plotting-script direkte i dit Bash shellscript med et Heredoc.
Et heredoc giver dig mulighed for at sende flere linier med kommandoer til et program. Her er et eksempel:
claus@ClausDesktop:~/work$ cat shellscript.sh #!/bin/bash echo "Hej fra Bash!" python <<HEREDOC print("Hej fra Python!") print("Hej igen fra Python!") HEREDOC echo "Hej igen fra Bash!" claus@ClausDesktop:~/work$ ./shellscript.sh Hej fra Bash! Hej fra Python! Hej igen fra Python! Hej igen fra Bash!
Du laver altså et Heredoc ved at skrive <<NAVN
, og afslutter det med at skrive NAVN
på en linie for sig selv.
I eksemplet ovenfor blev HEREDOC
brugt som navn, men mange bruger f.eks. EOF
eller END
i stedet - du kan også vælge et helt andet navn.
En vigtig fordel ved at bruge et Heredoc i stedet for et seperat script er, at du kan bruge variabler fra dit shellscript, se f.eks. dette eksempel:
claus@ClausDesktop:~/work$ cat shellscript.sh #!/bin/bash TAL="5.2" DYR="Hund" python <<HEREDOC a = 2.2 + $TAL print("Dyret er: $DYR") print("Tallet plus 2.2 er: " + str(a)) print("Foerste parameter er: $1") HEREDOC claus@ClausDesktop:~/work$ ./shellscript.sh Hello World! Dyret er: Hund Tallet plus 2.2 er: 7.4 Foerste parameter er: Hello
Du har nu set de vigtigste elementer i Bash shellscripts.