Bash-scripting

Har du noe lurt å dele med oss? NB. Dette er ikke et support forum.

Bash-scripting

Innleggav Abbath » søn 22.08.2004 3:05

Bash scripting er meget logisk og lett og kan spare deg for mye tid. Her er guiden som skal lære deg det grunnleggende innen BASH.

Hva er bash?
Bash står for Bourne Again Shell og er det vanligste skallet for linux. Bash-scripting kan blandt annet brukes til å forenkle jobber, lage installasjons programmer (tekstbaserte) .

Ditt først bash-script

Det første man gjør, er å lage et nytt tekstdokument. Vi kaller dette <filnavn>.sh (man må ikke ha endelsen .sh).
Det første scriptet vi skal lage, er et så kalt "Hello World"-script.
Dette vil skrive ut teksten "Hello World" på skjermen.
--------------------------------------------------------------------------------------
#!/bin/bash

echo "Hello World"
--------------------------------------------------------------------------------------

#!/bin/bash skal ALLTID være øverst i et bash-script.
Så enkelt var det. La oss hoppe videre.

Variabler

Å lage variabler i bash er heller ingen vanskelig sak. La oss si at du vil ha to variabler, hvorav den ene skal hete 'fornavn' og inneholde fornavnet ditt, og den andre hete 'etternavn' og inneholde etternavnet ditt.
--------------------------------------------------------------------------------------
#!/bin/bash
fornavn='Ola' # Setter variablen $fornavn til Ola
etternavn='Nordmann' # Setter variablen $etternavn til Nordmann.

echo "$fornavn $etternavn"
--------------------------------------------------------------------------------------
Merk at jeg brukte #-tegnet foran kommentarene. Alt som blir skrevet etter #-tegnet vil bli ignorert av scriptet. Scriptet over skal altså skrive "Ola Nordmann"

Read og echo

Du kan også bruke 'read' for at en person selv kan skrive hva en variabel skal være. La oss ta et eksempel hvor vi ber personen først å skrive inn fornavnet sitt, så etternavnet sitt og til slutt skrive dette på skjermen.
--------------------------------------------------------------------------------------
#!/bin/bash

echo -n "Skriv inn ditt fornavn: "
read fornavn

echo -n "Skriv inn ditt etternavn: "
read etternavn

echo "$fornavn $etternavn"
--------------------------------------------------------------------------------------
Legg merke til at jeg brukte 'echo -n' nå. -n gjør at man ikke bytter linje, slik at det personen skriver inn, kommer på samme linje og ikke linja under. Prøv deg gjerne fram og og legg til flere forskjellige variabler.
Man kan også legge til farger i teksten uten noe større problem:

Farger

Vi kommer kun til å benytte oss av hovedfargene. Her er en oversikt over fargekodene:
Rød = \033[1;31m
Grønn = \033[1;32m
Gul = \033[1;33m
Blå = \033[1;34m
Rosa = \033[1;35m
Lyseblå = \033[1;36m
Hvit = \033[1;37m
Slik bruker man farger:
--------------------------------------------------------------------------------------
#!/bin/bash

echo -e "\033[1;32mDenne teksten er grønn"
echo -e "\033[1;35mDenne teksten er rosa"
echo -e "\033[1;33mGul og \033[1;33mblå"
--------------------------------------------------------------------------------------
Man må alltid bruke 'echo -e' når man skal ha med farger. Håper du skjønte nok farger ved å se eksemplet over, for vi går ikke mer inn på dette med farger.

Så over til "del 2" av denne guiden

Skrive til fil
Å skrive til en fil er også en lett match i bash. Her er et eksempel:
--------------------------------------------------------------------------------------
#!/bin/bash
echo -n "Skriv inn ditt kallenavn: "
read nick # Det personen skriver, lagrer seg i $nick.

echo -n "Skriv inn ditt navn: "
read navn # Lagrer seg i $navn

# Så skal vi ha disse to linjene skrevet i en fil..Da gjør vi slik:

echo "Nick: $nick" >>filnavn.txt
echo "Navn: $navn" >>filnavn.txt

# >>filnavn.txt gjør at den skriver de linjene nederst i fila,
# og oppretter den om nøvendig.
--------------------------------------------------------------------------------------
La oss se hvordan dette scriptet vil se ut når det kjøres:

Skriv inn ditt kallenavn: mittnick
Skriv inn ditt navn: Ola Nordmann

Så åpner vi fila 'filnavn.txt', og den vil se slik ut:

Nick: mittnick
Navn: Ola Nordmann

Fila legger seg på samme sted som scriptet befinner seg, om ikke annet er oppgitt.

Bruke det vi kan til noe nyttig

Automatiske installasjons-script kan være meget nyttige. Hvis du for eksempel har en server som flere har tilgang til å starte prosesser i, kan et autoinstallasjon-script gjøre en jobb mye lettere. La oss ta et eksempel:
--------------------------------------------------------------------------------------
#!/bin/bash

echo -e "\033[1;33mAutoinstallasjon!"

# Laster ned det eventuelle programmet:
wget http://www.programurl.com/program.tar.gz
# Unzipper programmet:
tar -zxf program.tar.gz

cd program/ # Går inn i mappen til programmet.

# Nå kan du sette scriptet til å installere programmet, helt automatisk.
# Men siden vi vil ha det litt 'fancy', bruker vi noen enkle triks som gjør
# alt mye penere.
echo -en "\033[1;33mStarter å konfigurere programmet: "
./configure > /dev/null
echo -e "\033[1;32mFerdig!"
# Disse enkle linjene over, gjør installasjonen mye, mye penere.
# I steden for å se alt det 'våset' ./configure vanligvis vil gi, står det
# bare 'Starter å konfigurere programmet:
# Og når programmet er ferdig konfigurert, står det:
# 'Starter å konfigurere programmet: Ferdig!

# Skjønner? La oss gå vidre. Vi gjør det samme med 'make'
echo -en "\033[1;33mStarter å kompilere programmet: "
make < /dev/null
echo -e "\033[1;32mFerdig!"

# Vi kan gjenta det samme med en eventuell 'make install'
echo "Programmet er ferdig installert"
--------------------------------------------------------------------------------------
Håper ikke dette ble alt for mye på en gang.
PS: < /dev/null på slutten av ./configure og make hiver all den teksten ./configure og make vanligvis ville skrevet til /dev/null, slik at man slipper å se den.

If

Bruk av 'if' er veldig obligatorisk og sentralt. If er også ganske lett. Hodevrgelen for if er: if [ "$variabel" = "tekst" ];then
Det finnes selvfølgelig mange forskjellige typer, men her er kanskje den mest brukte. La oss ta et eksempel:
--------------------------------------------------------------------------------------
#!/bin/bash

echo -n "Kjører dette scriptet? Svar ja eller nei: "
read svar

# Her kommer selve trikset:
if [ "$svar" = "ja" ];then
echo "Det har du jammen rettt i, men ikke nå mer :)"
exit 0
else
echo "Ikke? Du har jo delvis rett.
exit 0
fi
## Enkelt, eller hva?
--------------------------------------------------------------------------------------
Helt feilfritt blir det jo ikke, men det fungerer mer enn godt nok. Man må alltid bruke 'else' også, ellers vil du få noen ufine feilmeldinger når du kjører scriptet. Husk at du ALLTID avslutter if med 'fi' som står for finish.

Man kan jo selvfølgelig bruke noe annet enn = i if. Bare se her:
if [ "$variabel" != "tekst" ];then # Hvis $variabel IKKE er lik tekst.

if [ "tekst" isin "$variabel" ];then #Hvis 'tekst' er i variablen $variabel.

Cut og awk

Awk kan være veldig kjekt. Det brukes til bare vise et ord i en linje.
La oss ta et eksempel. Vi bruker 'host bash.no' kommandoen, dette viser en linje som er slik (ca):
bash.no has address 195.18.186.6
Vi vil bare at den skal vise IP'en til bash.no, ikke alt det andre. Da lager vi et bash-script:
--------------------------------------------------------------------------------------
#!/bin/bash

echo -n "Skriv inn hosten du vil sjekke opp: "
# I dette eksemplet er det bash.no
read dnshost

# Og her kommer magien:
echo "`host $dnshost`" |awk '{ print $4 }'
# Hvorfor? Med print $4 viser den bare det fjerde ordet av linjen.
# Husk å bruke |-tegnet!
--------------------------------------------------------------------------------------
Litt mer avansert awk.
La oss si at vi kjører kommandoen "uptime" og den vil se slik ut:
02:45:34 up 69 days, 6:16, 8 users, load average: 0.00, 0.00, 0.00
Vi vil kun vise loaden, altså det som står etter "load average"
Da kjører vi dette inn i et bash-script.
--------------------------------------------------------------------------------------
#!/bin/bash

echo "`uptime`" |awk '{print $10 " " $11 " " $12}'
--------------------------------------------------------------------------------------
Dette gjør at den kun viser ord nr. 10, 11 og 12. "-tegnene gjør slik at det blir mellomrom mellom de forskjellige ordene. Vi kan selvfølgelig også bruke cut til å gjøre dette:

Cut:
Hvis vi har et ord beståendes av flere ord, som for eksempel 'menneskerettighetserklæringen'. Dette ordet vil vi dele opp slik at det kun står 'menneske'. Da lager vi et bash-script:
--------------------------------------------------------------------------------------#!/bin/bash

# Først ser vi at ordet menneske har 8 bokstaver.
echo "menneskerettighetserklæringen" |cut -c -8
# -c gjør at den teller bokstaver og -8 gjør at den kun viser bokstavene
# fram til bokstav nummer åtte.

# Vi kan også forandre litt på denne:
echo "menneskerettighetserklæringen" |cut -c 8-
# Nå viser den alle bokstavene etter bokstav nummer åtte.
--------------------------------------------------------------------------------------
Så går vi direkte til "del 3"

Timed Input
Det første vi skal ta for oss i del 3, er "Timed Input"
Det er ikke veldig vesentlig, men kan være greit å få med.
Timed Input gir deg så og så lang tid på å skrive inn noe.
Her er et eksempel:
--------------------------------------------------------------------------------------
#!/bin/bash

TIMELIMIT=5 # Gjør at man har 5 sekunder på å skrive inn..Kan byttes.

PrintSvar() # Dette lager en 'variabel' med mer enn en linje
{ # Her starter den.
if [ "$svar" = TIMEOUT ] # Hvis man bruker mer enn 5 sekunder.
then
echo $svar # Skriver ut $svar som er definert lenger ned..
else
echo "Ditt favorittdyr er $svar"
kill $! # Dreper TimerOn som kjørte i bakgrunnen.
# $! er PID'en til den siste jobben som kjørte.
fi
} # Ferdig..

TimerOn()
{ # Start
sleep $TIMELIMIT && kill -s 14 $$ &
# Venter i 5 sekunder, så sender den erroren.
} #Ferdig

Int14Vector()
{ # Start
svar="TIMEOUT"
PrintSvar
exit 14
} # Ferdig

trap Int14Vector14 # Vanskelig å forklare..

echo -n Skriv inn ditt favoritt dyr: "
TimerOn
read svar
PrintSvar

exit 0
--------------------------------------------------------------------------------------
Skjønte ingenting? Jeg forventer ikke at de fleste vil skjønne alt av dette, men det er vanskelig å forklare alt like lett. Med tanke på kunnskapene de fleste som leser denne guiden har, regnes denne som avansert.

"Er jeg root?"-script

Dette scriptet sjekker om du er root. Kan være kjekt om du skal lage et script som kun roots kan kjøre..
--------------------------------------------------------------------------------------
#!/bin/bash

ROOT=0 # Root har $UID 0

if [ "$UID" -eq "$ROOT" ] # -eq betyr equal, altså hvis root = 0
then
echo "Du er root."
else
echo "Du er bare en vanlig bruker."
fi
--------------------------------------------------------------------------------------
Det var vel enkelt?

While
While kan være nyttig...Her ser du et eksempel på while.
Dette scriptet skal reptere en linje så og så mange ganger
--------------------------------------------------------------------------------------
#!/bin/bash

echo -n "Skriv inn en linje som skal repeteres: "
read repline

echo -n "Hvor mange ganger skal den repeteres? "
read replimit

# Og her er magien:
a=1 # Setter $a til 1
while [ "$a" -le $replimit ] # Når $a = $replimit, skal den gjøre dette:
do # Vi bruker 'do' i steden for 'then'
echo "$repline"
let "a+=1" # Gjør at $a blir 1 mer for hver gang.
done # Vi bruker 'done' i steden for 'fi'
--------------------------------------------------------------------------------------

For loop
Her er et enkelt loop script:
--------------------------------------------------------------------------------------
#!/bin/bash

for tall in 1 2 3 4 5 6 7 8 9 # Dette blir da variablen $tall
do
echo $tall # Skriver hvert av tallene over på hver sin linje
done
--------------------------------------------------------------------------------------

En litt mer nyttig form for loop:
--------------------------------------------------------------------------------------
for file in /home/*/*.sh
do
cat $file | sed 's/hei/hallo/' > tempfile && mv tempfile $file
done
--------------------------------------------------------------------------------------
Scriptet over sjekker alle filene med endelsen .sh i alle brukernes home-dir og bytter teksten "hei" til "hallo", hvis dokumentet inneholder "hei".


Hvis det er noe mer du ønsker jeg skal gå igjennom, så si gjerne i fra. Jeg kan ikke love at det blir gjennomgått, men jeg får se hva jeg får til.
Sist endret av Abbath den lør 28.08.2004 13:43, endret 1 gang
medlem i 203 måneder
 

Innleggav Fivel » søn 22.08.2004 9:14

Hei Abbath!

Jeg har sett på denne guiden din, og synest det er en strålende innføring.

Jeg prøver meg litt på scripting selv, og så at du nevnte "isin". Jeg har prøv med "isin"eksemplelet du bruker, her:
Kode: Merk alt
                   if [ "tekst" isin "$a1" ];then
                           echo "Yess!!"
                           exit 0
                   fi
men får da
Kode: Merk alt
./test.sh: line 26: [: isin: binary operator expected


Hva gjør jeg galt? :oops:

Brukerens avatar
medlem i 203 måneder
 

Innleggav dewk » søn 22.08.2004 17:16

En meget fin innføring i bash-scripting :-)

Flott jobbet.
medlem i 203 måneder
 

Innleggav Are » søn 26.09.2004 20:06

Meget fin guide.
Har selv også skrevet noe relatert bash.
Er en guide om hvordan du modifiserer din bash-propt.
Her er guiden som jeg sendte inn til ITpro
medlem i 203 måneder
 

Innleggav alexb » tir 04.01.2005 16:56

Abbath, kunne du ha GFDL*-et denne teksten og lagt den inn i Linuxguiden?


*GNU Free Documentation License.
medlem i 199 måneder
 

Innleggav EvenHolthe » fre 31.03.2006 17:23

Kode: Merk alt
#!/bin/bash
echo -n "Skriv URL (med http): "
read url
clear
lynx -dump -head "$url" | grep Server


:D
medlem i 197 måneder
 

Innleggav nc » tor 22.02.2007 9:54

# Skjønner? La oss gå vidre. Vi gjør det samme med 'make'
echo -en "\033[1;33mStarter å kompilere programmet: "
make < /dev/null
echo -e "\033[1;32mFerdig!"

# Vi kan gjenta det samme med en eventuell 'make install'
echo "Programmet er ferdig installert"
--------------------------------------------------------------------------------------
Håper ikke dette ble alt for mye på en gang.
PS: < /dev/null på slutten av ./configure og make hiver all den teksten ./configure og make vanligvis ville skrevet til /dev/null, slik at man slipper å se den.



Bare ett par små skriveleif'er... :-) "Krokodilletegnet" skal vel peke motsatt vei for å dirigere output fra kommandoen til /dev/null, og ikke at /dev/null skal inn i kommandoen... ;)

Erfaren
Brukerens avatar
medlem i 198 måneder
 

Innleggav geirendre » tor 22.02.2007 13:12

Fin introduksjon, grei og lettfattelig.
Og når man føler seg klar, kan man jo fortsette
med Advanced Bash Scripting Guide
http://tldp.org/LDP/abs/html/
for litt mere viderekommende scripting.

PS. AWK kan brukes til mye mere enn bare å
hente et ord ut fra en streng.
AWK er faktisk et eget språk.
http://allman.rhon.itam.mx/dcomp/awk.html
og du kan gjøre mye med en enkel linje i AWK
http://www.softpanorama.org/Tools/Awk/awk_one_liners.shtml

Støter man på problemer med syntax etc. kan det være verd å
søke gjennom basen til Tek-Tips.com , de har forum for
de fleste programmeringsspråk inkl. AWK og Unix-scripting.
http://www.tek-tips.com/subscribetoforums.cfm?Lev2=Programmers&Lev3=Languages
Happy hacking ;)

Erfaren
Brukerens avatar
medlem i 197 måneder
 

Innleggav rhka » søn 22.07.2007 23:08

Hvis jeg taster følgende i en terminal, så startes firefox med siden til google.com og frigjør terminalen:
firefox google.com &

Jeg vil legge følgende kommando som alias f i .bashrc:
alias f='firefox $1 &'

Når jeg etterpå prøver å taste f google.com, så kommer en feilmelding om at kommando google.com ikke finnes, og firefox starter på standard side.
Hvis jeg skriver aliasen som alias f='firefox' så kan jeg taste f google.com, men da blir ikke terminalen frigjort.

Er det noen som vet hvordan en slik alias skal skrives?
medlem i 176 måneder
 

Innleggav simen » søn 22.07.2007 23:54

Bash scripting blir for usikkert (ikke sikkerhetsmessig) for meg. For mye string manipulasjon. En ting du skriver i en Linux distro er kanskje ikke sann i en annen da outputen er annerledes. Og det som da cut -f7 kutter i kolonne 7 er kanskje noe helt annet i denne distroen enn den andre. Også har vedkommende bsd ls, ps, etc... eller dem til gnu? Etc...

Men bra guide :) Selv bruker jeg perl til scripting på kommandolinja. Jeg liker å spørre funksjoner om info, ikke en string som jeg så manipulere og kutter resultatet ut fra :)

Bash scripting kunne blitt mye mer kraftig om de som lagde programmene til Linux i større grad brukte null byte til å skille tegn og ikke spaces. Burde da hatt en egen opsjon for scripting, altså skilletegn med null byte. Også om man kunne bestemme åssen info man ville ha. Slik at man slapp å string manipulere over 7 kolonner for å få det man ville ha. Dette også for hastighetens skyld.

Brukerens avatar
medlem i 217 måneder
 

Innleggav TO » man 23.07.2007 0:49

Legg f.eks. denne i din .bashrc, start ny terminal eller kjør $ source .bashrc
Kode: Merk alt
function f {   
firefox "$@" &
}

Bruk: $ f http://www.google.com

I boka "Learning The Bash Shell" så sier de at funksjoner er nyttigere enn aliaser. Det kommer ant på formålet, skal du programmere noe, bruke argumenter eller frigjøre terminalen - bruk en funksjon.
medlem i 180 måneder
 

Innleggav rhka » man 23.07.2007 1:43

Tusen takk! Jeg fikk mer enn jeg ba om.

Da ser min .bashrc slik ut (kanskje av interesse for andre newbies.):
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Lagt til av Henning
# Kjør source .bashrc etterpå for å oppdatere med denne filen, så slipper du å avslutte og starte opp terminalen igjen.
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias l='echo "*************************************************************************************************"'
alias la='ls -la' # Lang liste med alle filer.
alias r='reset' # Tømmer og resetter skjerm.
alias c='clear' # Tømmer skjerm.
alias e='eject' # Åpner CD. Mest for moro.
alias ee='eject -t' # Lukker CD.
alias virus='clamscan -ri --bell /' # Installer og opdater først. Denne fant 2 virus som Norton og F-secure ikke fant.

# Skal du programmere noe, bruke argumenter eller frigjøre terminalen - bruk en funksjon.
function f { # Starter firefox med den url du taster og frigjør terminalen.
firefox "$@" &
}
function g { # Starter gedit med den filen du taster og frigjør terminalen.
gedit "$@" &
}

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

Denne filen tilhører root i Fedora 6. Noen kommentarer/tips fra de mere erfarne?
Jeg har lagt merke til at alle enkeltstående bokstaver er ledige for bruk, ingen kommandoer på bare en bokstav; kjekt for den som vil tilpasse snare snarveier.

Henning
medlem i 176 måneder
 

Re: Bash-scripting

Innleggav Raven80 » søn 05.07.2009 9:41

Hei.

sitter å forsker litt på dette.

Men hvordan kjører jeg scriptet?

Feks første script "hello world"
medlem i 168 måneder
 

Re: Bash-scripting

Innleggav moma » søn 05.07.2009 9:57

Hei,

Her er 2 måter du kan kjøre skriptet på.
Jeg antar at du står i katalogen der du lagret skriptet.

1) Gjør skriptet kjørbar med chmod. F.eks
$ chmod +x skript1.sh
og kjør det med
$ ./skript1.sh

Du kan også sette skriptet kjørbar i GUI (konqueror, nautilus osv.) og bare klikke på filen for å kjøre.

2) Kjør skriptet direkte vha bash eller sh.
$ sh skript1.sh

3) Du kan også kjøre skriptet i gjeldende shellet. Denne starter ikke noe nytt shell.
(du skriver . først).
$ . ./skript1.sh

Se også: http://tldp.org/LDP/abs/html/

Erfaren
Brukerens avatar
medlem i 202 måneder
 

Re: Bash-scripting

Innleggav Raven80 » søn 05.07.2009 10:05

ok, Takk.

Men hva er forskjellen på disse to kommadoene?

EDIT:

Kan jeg lage bash-script for å ta backup av F.eks /home?
medlem i 168 måneder
 

Neste

Returner til Tips og triks / Favoritter



Hvem er i Forumene

Registrerte brukere: Ingen registrerte brukere