Olika shell Csh-kompatibla csh - C shell tcsh Standardshellet för terminaler på institutionen Bourne-kompatibla sh - Bourne shell. Används ofta för script bash - Bourne again shell. Man kan byta till detta shell om man vill på institutionen ksh - Korn shell pdksh - public domain-variant av ksh zsh Kan också väljas som inloggningsshell på inst 81 82 Pipor och omdirigering av strömmar Med en pipa kan man låta ett kommando läsa från utdatat av ett annat Åstadkoms genom att man skriver ett mellan kommandona Ex: ls wc Stdin, stdout och stderr kan också omdirigeras till ler I tcsh: stdin < stdout > stderr och stdout >& Ex: cat *.c > l.txt 83 Skalprogrammering I stället för att skriva ett program för att göra något i en Unix-miljö så det i vissa situationer betydligt vanligare, enklare och snabbare att skriva ett shell-script. Varför inte C-program? Visst kan man skriva ett C program som gör det man vill men ofta så vill man göra något som är relativt lätt att uttrycka men att skriva de i C blir komplicerat. Exempel: du vill ha en speciell version av "ls" som bara skriver ut ler där "others" har rättigheterna "rwx". För att göra ett sådan program måste du använda dig av t.ex. lstat och sedan läsa rättigheter etc etc etc och sedan vill jag naturligtvis ha alla de vanliga grejorna som ls har.... det måste nnas något enklare sätt. 84
Skalprogram Det bästa vore att på något sätt modiera "ls" men det är ju inte så enkelt om man inte har källkoden... plus att man ställer till en massa problem för andra som använder "ls" för att inte tala om de eventuella buggar man introducerar när man ändrar i programmet. Så vad kan man göra? Jo, om jag tittar lite på olika kommandon så ser jag att det nns ett program som heter "grep". Grep Grep letar efter vissa mönster i en textl och skriver ut de rader som innehåller dessa mönster (eller de som inte innehåller dem). T.ex. så om jag har en l, med namnet 'demol' som ser ut så här: Titta en liten lista över vilka töntiga ord man kan hitta på för en exempeltext så att man har nåt att visa. Om jag nu skriver "grep en demol" så blir resultatet Titta en liten lista över hitta på för en exempeltext 85 86 Sätta i hop kommandon Det jag vill lista är de ler som har "rwx" för 'others". Genom att använda "ls -l" så får jag en lista över lerna där varje rad börjar på ungefär detta sätt: -rw-r--r-- johane tdb Det intressanta är här de första tecknen. Om jag på något sätt kan kolla bokstäverna 8-10 på varje rad och se om de är "rwx" så har jag xat det. Jag skulle kunna använda en pipe att skicka resultatet från "ls -l" till grep, dvs. någonting i denna stil ls -l grep 87 Reguljära uttryck Det nns ett sätt att beskriva mönster i text, det kallas reguljära uttryck och gör att kolla bokstäverna om bokstäverna 8-10 innehåller "rwx" skriver man "^...rwx". "^" tolkas som "början på raden", "." som "vilket tecken som helst". Med andra ord så betyder "^...rwx": en rad som börjar med 7 godtyckliga tecken följt av "rwx". 88
Ny version av kommandon Nu kan jag alltså skriva ls -l grep ^...rwx och få en listning av de ler som uppfyller kravet. Om jag skriver in texten i en l och kallar den 'listorwx' så kan jag skriva sh listorwx och få samma resultat #! Nackdelen ovan är att jag måste skriva detta hela tiden... måste nnas något bättre sätt? Genom att lägga till en ny rad först i len som ser ut så här och sedan ändra lens rättigheter så att den blir exekverbar så har jag skapat ett program som jag kan starta genom att skriva listorwx och få önskat resultat 89 90 Utöka systemprogramvaran Personligen ser jag på shellscripts så ett bekvämt och snabbt sätt att utöka plattformens funktionalitet. Jag rekommenderar starkt att ni lär er utnyttja shellscripts om ni ska använda en UNIX- eller Linux- plattform. Samma sak gäller om ni använder Mac (AppleScript och shellscripts) eller Windows: lär er att styra er dator Det nns flera olika skal och alla kan användas för att skriva shellscripts (även om inte alla är så lämpliga), ett vanligt skall är sh. #! Ett shellscript måste börja med "#!" följt av sökvägen till det skalprogram som ska köras, t.ex. Om du inte har detta så kommer du antagligen att få ett felmeddelanden. På den raden kan man också lägga in olika options till det skalprogram man använder. 91 92
Variabler % pwd /Home/staff/mr %./mycd /etc % pwd /Home/staff/mr mycd cd /etc pwd Man kan deniera variabler i shellscripts demovariable= Hi there echo $demovariable Bara en datatyp "strängar". Man kan också kolla om variabler och denierade genom att använda följande kommandon: Innebär t ex att alla variabler mm man skapar i ett script är lokala för scriptet 93 94 Olika citationstecken ${variabel:-värde} Om variabeln existerar och har ett värde så används detta värde i annat fall så används värdet 'värde ${variabel:=värde} Om variabeln inte existerar eller inte har nåt värde skapas variabeln och sätts till värdet 'värde ${variabel:+värde} Om variabeln existerar och har ett värde så används 'värde' annars blir det en tom sträng. ${variabel:?värde} Om variabeln existerar och har ett värde så använd det. I annat fall så skrivs 'värde' ut och avslutas. 95 Dubbelsnutt Om man börjar/slutar en sträng med " så kommer det att ske en variabelsubstitution när man evaluerar uttrycket echo "$1 $2" Enkelsnutt Ingen variabelsubstitution echo '$1 $2' Bakåtsnutt Det som skrivs ut av ett kommando examp=`ls` 96
Beräkningar Lite besvärligt antal=`expr "$i" + 1` Kontrollstrukturer Det nns även ett antal olika kontrollstrukturer som man kan använda (annars vore det tämligen oanvändbart). Sant/falskt Tvärtom från C, 0 är sant och icke-0 är falskt 97 98 if ls /nnsinte; then echo "... där var innehållet i /nnsinte else echo "Fel vid listning av /nnsinte En annan variant if ls /hubba; then echo "... och där var innehållet i /hubba elif ls /bubba; then echo "...och där var innehållet i /bubba else echo "Fel vid listning av /hubba och /bubba test Man kan använda 'test' för att jämföra saker (OBS om du döper ett program till 'test' och sedan försöker köra det genom att skriva 'test' så är det det inbyggda 'test' som körs) if test "$a" = "$b"; then bla bla bla bla annat sätt att skriva det på if [ "$a" = "$b ]; then bla bla bla bla Kan också användas till att kolla ler (om de existerar är läsbara osv.) 99 100
test w le (har len skrivrättigheter?) -r (läsrättigheter?) -x (exekveringsrättigheter?) -s (är len icketom?) test nr1 eq nr2 (är tal1 lika med tal2?) -ne (är tal1 skilt ifrån tal2?) -gt (är tal1 större än tal2?) test str1 = str2 (är sträng1 lika med sträng2?)!= (är sträng1 skilt ifrån sträng2?) 101 $? Innehåller returvärdet från det senaste kommandot anexamplecommand myresult="$? if [ "$myresult" -eq 0 ] ; then bla bla bla bla 102 case Det nns en switchliknande sats också maskin=`uname -n` case $maskin in peppar) echo "Sun-server" ;; jumjum) echo "Sun-arbetsstation" ;; garnet) echo "SGI-arbetsstation" ;; *) echo "Okänd exit ;; esac for Man kan också loopa över innehållet i en lista for n in This is a list do echo $n Man kan använda "break" för att hoppa ur en for sats 103 104
while while [ "$a"!= "$b" ] do b=`kommando` until until who grep "^johane do sleep 60 echo "Nu har Johan loggat in" 105 106 och && Används för att göra något om nåt annat lyckades/misslyckades. En sorts mini-if cat l1 l2 > l3 exit cat l1 l2 > l3 { echo "Hopslagningen funkade inte exit } lpr -Pprinternamn "$l" && rm "$l" Om man använder så betyder det att man gör det som kommer efter om det som var före returnerar ett värde skiljt från 0. && gör tvärtom. Läsa in värden Man kan använda "read" för att läsa en rad, läser till radslutet. read lnamn echo $lnamn 107 108
Kommandoradsargument Man kan komma åt kommadoradsargumenten genom att använda $0, $1, etc. Så genom en enkel modiering av list-scriptet så kan vi skicka med argument olika till ls kommandot och få den flexibilitet vi ville ha. ls -l $* grep "^...rwx $* betyder alla argument. Funktioner Man kan deniera funktioner också till_l(){ echo "Lägger till $1 till len $2. echo "$1" >> $2 } for n in knatte fnatte tjatte do till_l "$n" "personer 109 110 if [ $# -lt 1 ]; then echo 1>&2 "Usage: $0 [-l] le [le...]" exit 1 if [ $1 = "-l" ]; then command="ls -l shift else command="ls" while [ $# -ge 1 ]; do $command $1 shift exit 0; 111 boule[48] ~ %./myls Usage:./myls [-l] le [le...] boule[49] ~ %./myls l ls: cannot access l: No such le or directory boule[50] ~ %./myls a.out tt.c myls a.out tt.c myls boule[51] ~ %./myls -l a.out tt.c myls -rwx------ 1 mr tdb 6456 2010-03-02 13:31 a.out -rw------- 1 mr tdb 152 2010-03-02 13:36 tt.c -rwx------ 1 mr tdb 241 2010-04-09 10:50 myls boule[52] ~ % 112
-x boule[53] ~ %./myls -l a.out tt.c myls + '[' 4 -lt 1 ']' + '[' -l = -l ']' + command='ls -l' + shift + '[' 3 -ge 1 ']' + ls -l a.out -rwx------ 1 mr tdb 6456 2010-03-02 13:31 a.out + shift + '[' 2 -ge 1 ']' + ls -l tt.c -rw------- 1 mr tdb 152 2010-03-02 13:36 tt.c... 113 if [ $# -lt 1 ]; then echo 1>&2 "Usage: $0 pdfle" exit 1 tot_pages=`pdnfo $1 grep Pages cut -d: -f2` nr_pages=2 i=1 tmple="/tmp/$1_$$.ps" if pdf2ps $1 $tmple; then while [ $i -lt $tot_pages ]; do let j=$i+$nr_pages-1 psselect -p$i-$j $tmple lpr -Pgutenberg Zstaple let i=$i+2 rm -rf $tmple else echo 1>&2 "Error using pdf2ps" exit 1 114