Bourne-again Shell

Bourne-again Shell
Generelt om shell / skall
●
Kommandolinjebasert brukergrensesnitt (CLI)
●
Leser en og en linje med tekstlig input
●
●
●
Inputlinjene er kommandoer som skal utføres
eller programmer som skal startes
Shellet interpreterer (tolker) input, finner ut hva
som skal utføres og starter utføringen
Kommandoer til shellet kan også leses fra en
tekstfil – et shellscript (skallprogram)
Fordeler ved å bruke et shell
●
●
●
●
Kommandolinjen gir (veldig) mye bedre kontroll
og fleksibilitet enn et GUI
Kommandoene har mange opsjoner som enkelt
endrer måten de virker på
Tekstbaserte programmer er raskere og mindre
ressurskrevende enn GUI
Shell er enkelt å “skreddersy”, programmere og
automatisere
●
Enkel tilgang til maskiner andre steder på nettet
●
Bruker bare tastaturet, slipper musesyke o.l.
Ulemper ved å bruke shell
●
Shellene ble laget “av eksperter for eksperter”
●
Mindre intuitivt enn et GUI, vanskeligere å lære
●
Enklere i GUI:
●
–
Enkle operasjoner som f.eks. copy/paste
–
Multitasking/bytting mellom vinduer
Gammeldags og kjedelig i forhold til et GUI?
Litt shell-historikk
●
Thompson shell
–
●
●
●
Første programmerbare shell, 1971
Bourne shell (sh):
–
Stephen Bourne, Bell Labs, ca 1977
–
“Fullblods” programmeringsomgivelse
–
Finnes fortsatt på alle Linux/Unix maskiner (sort of)
Bourne-again shell (bash):
–
Brian Fox/GNU, 1989
–
Bakoverkompatibel videreutvikling av sh
–
Mest brukte Linux-shell
Finnes mange andre shell som fortsatt er i bruk:
–
C shell (BSD Unix), Korn shell, Z shell, Almquist shell, Busybox ++
Kommandolinjen i Linux
●
●
●
Prompt / ledetekst: janh@ask:~$
–
Brukernavn
–
Navn på datamaskin
–
Stående katalog ( ~ = brukers hjemmeområde )
–
$ = “venter på input” (# for superbruker/admin/root)
–
Prompt kan settes til å være “hva som helst”
Shellet tolker og starter kommando etter at bruker
taster enter
Flere kommandoer kan gis på samme linje ved å
skille dem med ; (semikolon)
Noen enkle kommandoer
pwd
skriv ut navn på stående katalog
ls
skriv ut innholdet i stående katalog
passwd
endre passordet for innlogging
who
hvem er logget på Linux-systemet?
bash
start et nytt (sub)shell
exit
avslutt shellet (logg av maskinen?)
Opsjoner og parametre til kommandoer
De fleste Linux-kommandoer kan ta i mot to ulike typer
argumenter (inn-verdier) på kommandolinjen:
●
Opsjoner:
–
●
Parametre:
–
●
Endrer virkemåten for kommandoen
Angir hva kommandoen skal “jobbe med”
Linux kommandosyntaks * :
kommando [opsjoner] [parametre]
*: [] betyr at “dette er valgfritt” (null eller flere)
Opsjoner
●
Endrer virkemåten til kommandoen
●
Begynner (nesten) alltid med tegnet ­ (bindestrek)
●
Består ofte bare av ett tegn
●
Flere opsjoner kan “klumpes sammen”
●
Eksempler:
ls ­l
ls ­lt
ls ­l ­t
ls ­ltaR
List filene i stående katalog i “langt format”
Og i tillegg sortert på tidsstempel (med og uten
“klumping” av opsjoner)
List også “skjulte filer”, og list filene i alle
underkataloger av stående katalog (rekursivt)
Parametre
●
Angir hva kommandoen skal “jobbe med”
●
Er oftest filnavn eller tekststrenger:
ls fil1.txt fil2.txt fil3.txt fil4.txt
grep Høiberg navneliste.dat
●
●
Mange Linux-kommandoer kan ha et ubegrenset antall
parametre
Grupper av parametre (spesielt filnavn) kan angis ved å
bruke jokernotasjon (wildcards):
ls *.txt Dokumentasjon av Linux-kommandoer
●
●
man kommando
–
man viser manualsidene for en Linux-kommando
–
Manualsider er relativt tekniske og detaljerte
–
Har innebygget “lesekommandoer” (egentlig kommandoen less) for å
bla frem og tilbake, søke og flytte rundt i teksten
–
Kommandoen 'h' gir oversikt over “lesekommandoene”
Annen dokumentasjon av Linux-kommandoer:
–
apropos
Søker etter ord i manualsidene
–
info
Viser “full documentation” for en kommando *
–
help
Dokumentasjon av “innebyggede” Bash-kommandoer
(se man builtins )
*: Skrevet i et mer fullstendig og lettlest språk enn manualsidene
Kommandohistorie
●
Bash lagrer alle kommandoer som gis, i en liste
●
history: vis nummerert liste med kommandohistorie
●
●
●
Tegnet '!' (utropstegn, aka “bang”) brukes til å hente frem
og kjøre på nytt kommandoer fra listen:
!#
Utfør kommando nummer #
!!
Utfør sist gitte kommando
!s
Utfør sist gitte kommando som starter med “s”
history er en “innebygget” kommando i Bash
Kommandohistorien kan slettes, redigeres, lagres og
oppdateres, se lærebokens avsnitt 2.4.1 eller prøv:
help history | more
Skallvariable / Shell variables
●
Brukes til å lagre informasjon og verdier i shellet
●
Refereres til med variabelnavn:
●
–
Variabelnavn kan inneholde a-z A-Z 0-9 og _ (underscore)
–
Må begynne med en bokstav eller _
Variable i shell er uten type:
–
Lagrer bytes
–
Tolkes som enten tekststrenger eller heltall (eller arrays)
Opprette og bruke variable
●
Skallvariable trenger ikke å deklareres, de opprettes
automatisk ved første referanse til variabelen:
VAR=verdi
●
For å bruke variabelen / hente ut verdien:
$VAR
eller
${VAR}
●
Sette en variabel lik en annen:
VAR_2=$VAR
●
Tegnet '$' er et (av mange) spesialtegn i shellet
Eksempel:
Tilordning og bruk av variabel
FARGE=Rød
echo $FARGE
echo $FARGEaktig (*)
echo ${FARGE}aktig
FARGE_2=Grønn; FARGE_3=$FARGE
echo FARGE $FARGE $FARGE_2 $FARGE_3
(*): Gir ikke feilmelding, men oppretter en ny variabel med verdien NULL
Enkel output i Bash: echo
●
Generell utskriftskommando i skallet
●
echo skriver ut en linje med tekst til skjermen
●
Opsjonen ­n gjør at det ikke skrives ut linjeskift
●
echo er “innebygget” i Bash*, for dokumentasjon se:
help echo | less
●
For å skrive ut spesialtegn i shellet (som f.eks. *, &, $,
| , \, “) må vi sette en '\' (backslash, “escape”) foran
tegnet
*: Det finnes også en GNU-echo, dokumentert i man echo
Miljøvariable / Environment variables
●
●
●
●
●
Systemvariable som opprettes og får verdier ved
oppstart av maskinen og/eller ved innlogging av bruker
Inneholder viktig systeminformasjon, og parametre som
bestemmer hvorledes shellet skal “oppføre seg”
Varierer mellom ulike Linux-systemer
Ikke endre på miljøvariable hvis du ikke vet hva du
holder på med!
Se på innholdet av alle miljøvariable: env
Noen standard miljøvariable
USER
Brukernavn
HOME
Brukers hjemmekatalog
HOSTNAME
Navn på datamaskinen
MAIL
Brukers mailkatalog
PWD
Stående katalog
SHELL
Shellet som skal startes ved innlogging
HISTSIZE
Lengden på listen med kommandohistorie
PATH Katalogene der shellet finner kommandoer
PS1
Bestemmer innholdet i prompt/ledetekst
(se side 51 i læreboken)
alias
●
●
Et alias ligner på en skallvariabel, men brukes til
å lagre en Linux-kommando
Syntaks:
●
alias navn='kommando'
alias kan brukes til å:
–
Lage kortversjoner av lange, kompliserte og/eller
ofte brukte kommandoer
–
La vanlige tastefeil bli tolket som korrekt input
–
Gjøre “farlige” kommandoer sikrere å bruke
alias eksempler
●
Forkortelse av (en eller flere) kommandoer:
alias lt='ls ­lt'
alias pl='pwd; ls'
●
“Korrigering” av skrivefeil:
alias sl=ls
●
Beskyttelse mot utilsiktet fjerning av filer:
rm='rm ­i'
●
Fjerne alias:
unalias navn
Editering av kommandolinjen i Bash
●
●
●
●
●
Alle som skal bruke Linux bør (må?) lære seg å
editere (redigere) teksten på kommandolinjen
Gjør Linux-bruk enklere og mye mer effektivt
“Oppoverpil” og “nedoverpil” brukes til å bla frem og
tilbake i kommandohistorien
Teksten på kommandolinjen redigeres med de samme
kommandoene som brukes i editoren emacs
Prøv selv kommandoene på side 53 i læreboken, eller
(enda bedre) gå gjennom opplæringsprogrammet i
emacs (se øvingsoppgavene til uke 34)
Linux filterprogrammer
●
●
Mange kommandoer i Linux er tekstbaserte filtre:
–
Leser en strøm av tekst/tegn, linje for linje
–
Gjør noe med (filtrerer) tekstlinjene
–
Skriver deretter ut filtrert tekst linje for linje
Input leses oftest fra standard innenhet – STDIN:
–
●
Output skrives til standard utenhet – STDOUT:
–
●
STDIN er i utgangspunktet (default) satt til å være tastaturet
STDOUT er i utgangspunktet terminalvinduet (skjermen)
Feilmeldinger skrives til standard feilenhet – STDERR:
–
STDERR er i utgangspunktet også terminalvinduet
Filbegrepet i Linux
●
Vanlig definisjon av en fil:
–
●
I Linux kan en fil også defineres som:
–
●
●
En samling data (bits og bytes) som logisk hører sammen,
f.eks. en tekstfil eller et program
En kilde der data kan leses fra, og/eller et sted/medium som
data kan skrives til
“Alt er filer” i Linux:
–
Vanlige diskfiler, men også mus, printere, skjerm, tastatur...
–
Alle I/O-enheter og nettverksporter representeres med en
systemfil (eg. en driver) som man kan lese fra eller skrive til
Betyr at STDIN, STDOUT og STDERR også er filer
STDIN, STDOUT og STDERR
●
●
●
Alle Linux-programmer har disse tre I/O-strømmene
(filene) åpne når programmet starter
STDIN, STDOUT og STDERR er egentlig
fildeskriptorer (file descriptors):
–
Et heltall som er en indeks i en tabell med info. om åpne filer
–
File descriptor 0 (null) er reservert for STDIN
–
File descriptor 1 er STDOUT, 2 er STDERR
Default oppsett er:
–
STDIN er systemfilen som representerer tastaturet
–
STDOUT og STDERR er begge systemfilen som
representerer terminalvinduet som programmet kjører i
Redirigering av I/O for Linux-kommandoer
●
Shellet tilbyr redirigering (redirection) av input og
output for Linux filterprogrammer:
–
Kan sette STDIN og STDOUT (og STDERR) til å være
filer i stedet for tastatur og skjerm
–
Betyr at det er lettvint (og elegant) å få Linuxkommandoene til å lese fra og skrive til filer
–
Kan også redirigere I/O slik at output fra en kommando
leses som input til neste kommando (interprosesskommunikasjon)
Spesialtegn for redirigering av I/O
> filnavn
Skriv output til fil, overskriv hvis filen finnes
>> filnavn
Skriv output til fil, “append” hvis filen finnes
< filnavn
Les input fra fil
<< [EOF]
Les input fra tastatur inntil EOF leses
(default End-Of-File tegn i Linux er ctrl-d)
|
Send output fra denne kommandoen som
input til neste kommando (pipe)
Enkelt eksempel: cat
●
cat
Kopierer det som tastes inn ut til skjermen
●
cat < fil_1
Viser innholdet av filen fil_1 på skjermen
●
cat < fil_1 > fil_2
Lager en kopi av fil_1 og lagrer denne i fil_2
●
cat < fil_1 >> fil_2
Legger til innholdet av fil_1 på slutten av fil_2
●
cat > fil_1
Det som tastes inn blir lagret i fil_1 (cat blir en teksteditor)
Redirigering: Flere eksempler
●
Liste med alle filene i stående katalog lagres på en fil:
ls > liste­fil
●
Legger til nåværende tidspunkt og en liste med alle
påloggede brukere på den samme filen:
date >> liste­fil
who >> liste­fil
●
Legger til de 20 siste linjene på en fil på slutten av en
annen fil :
tail ­20 < fil_1 >> fil_2
Beskyttelse av filer mot overskriving
●
Dette vil overskrive filen hvis den finnes fra før:
echo "Hello, world" > file.txt
●
For å unngå at redirigering av output skriver over filer:
set ­o noclobber (*)
●
Bash vil da gi feilmelding ved forsøk på å overskrive med >
●
Kan allikevel tvinge frem overskriving med operatoren >|
echo “Hello world” >| file.txt
●
For å sette Bash tilbake til “vanlig overskriving” med >
set +o noclobber
(*): Clobbering: "overwriting, usually unintentionally”
Piping / “rørlegging” i Linux
●
●
●
●
Sender output fra en kommando som input til en
annen kommando
Gjøres ved å sette tegnet '|' (“pipe” / “rør” / vertikal
strek) mellom to kommandoer
Kan også sette sammen tre eller flere kommandoer
med pipe i mellom – en pipeline
Internt i Linux foregår interprosesskommunikasjon:
–
Den første kommandoen skriver output til et buffer
–
Den andre kommandoen leser input fra det samme bufferet
Eksempler på piping *
●
Telle antall filer (og kataloger) i stående katalog:
ls | wc ­l
●
Sortere listen over innloggede brukere på brukernavn:
who | sort
●
Hvor mange brukere heter “Magnus”?:
ypcat passwd | grep ­w Magnus | wc ­l
●
Generere et tilfeldig passord på 32 tegn med bare tall og
bokstaver:
tr ­cd '[:alnum:]' < /dev/urandom | fold ­w32 |\
head ­n1
* Eksemplene inneholder flere kommandoer som vi skal studere senere i kurset
Noen flere nyttige Bash-mekanismer
●
Tilde expansion:
~
ditt eget hjemmeområde
~bruker
en annen brukers hjemmeområde
●
Jokernotasjon / wildcards (*, [], ?):
*
alle filer og kataloger i stående katalog
*.html
alle HTML-filer i stående katalog
●
Tab completion på kommandolinjen:
–
Trenger bare å skrive kommandoer og filnavn frem til de er
éntydige, en <tab> “fyller i resten”
–
To <tab> viser alle kommandoer/filnavn som matcher det
som er skrevet frem til nå
“Skreddersøm” av shellet
●
Egne aliaser, variable og kode som man ønsker at alltid
skal ligge i shellet, legges i oppstartfiler :
.profile
Utføres ved innlogging med alle shell
.bash_profile Utføres ved innlogging med bash
.bashrc
●
Utføres hver gang et nytt bash shell startes
Variable som skal være tilgjengelig i subshell eksporteres:
export variabelnavn
●
Oppstartfilene er egentlig scripts / skallprogrammer
●
Kan også kjøres direkte i det nåværende shellet:
source ~/.bashrc
Litt om interpretere og kompilatorer
●
●
Shell er en interpreterende omgivelse:
–
Leser, tolker/oversetter og utfører koden én linje om gangen
–
Best egnet til mindre applikasjoner (?)
–
Noen interpreterte språk: shell, LISP, Ruby, Python...
“Klassiske” programmeringsspråk bruker kompilator:
–
Hele programkoden oversettes til eksekverbar maskinkode
–
Kompileringen genererer oftest først “objektkode” som
deretter settes sammen og oversettes til maskinkode
–
Større programmer med krav til effektivitet krever kompilering
–
Noen kompilerende programmeringsspråk: C, C++,
FORTRAN, Java (sort of),...
Java – både kompilator og interpreter
●
Programmer skrevet i Java kompileres til byte code:
–
●
“Nesten” maskinkode, men uavhengig av hardware
Kompilert Java-kode kjøres av en Java Virtual
Machine (JVM) som er tilpasset hardware:
–
JVM inneholder hele miljøet som trengs for å eksekvere
Java-programmer, inkludert egen minnehåndtering
–
Inneholder også en interpreter som tolker og kjører Java
byte code
–
Interpreteringen går mye raskere enn vanlig interpretering
av kildekode i f.eks. shell
Interpretere i Linux shell
●
●
●
Linjebaserte interpretere egner seg godt til OS:
–
Hastighet ikke kritisk ved interaktivitet
–
Kompilering av kildekode passer ikke til interaktiv bruk
–
Effektivt og fleksibelt alternativ til GUI
Gir brukere mulighet til å lage egne interpreterte scripts/
skallprogrammer:
–
Interpreteren leser kommandoer fra fil i stedet for interaktivt
–
Linux shell tilbyr “fullblods” programmering med løkker, iftester, tabeller etc.
Linux-interpretere kjører i et miljø som enkelt kan
“skreddersys” til brukernes behov
Steg-for-steg virkemåte for interpreteren i Bash
1. Leser en linje med input fra tastatur eller fil
2. Splitter input opp i “tokens” (hele ord og operatorer)
3. Håndterer evt. anførselstegn (quotes) i input
4. Bytter ut aliaser med kommandoer
5. Splitter evt. input opp i flere kommandoer (hvis ';' er brukt)
6. Gjør alle “shell expansions”: ~, *, ?, {}, $
7. Setter opp alle redirigeringer av I/O, fjerner redirigering fra input
8. Utfører kommandoen(e)
9. Venter(?) til kommandoen(e) er ferdig.
10. Klar for å ta i mot neste linje med input.