Kapitel 3 Mer om skalet 3.1 Kommandorör ( ) Ni har sett hur man kan spara resultatet av ett kommando i en fil med hjälp av tecknet > och ett filnamn. Istället för att spara resultatet i en fil kan man också skicka vidare resultatet som indata till ett nytt kommando med tecknet (lodstreck). Detta kallas på engelska för en pipe. Man tänker sig att utdata från det första kommandot färdas i ett rör vidare till nästa kommando. På svenska sägs ibland kommandorör. Med head stp.txt, men istället för att skriva ut resultatet av det kommandot till terminalen så skickar skalet vidare det som indata till wc -w som räknar orden i det. De båda programmen head och wc vet inte om att de kommunicerar med varandra. Det första skriver utdata till standard output och det andra läser indata från standard input utan att veta vad som finns i andra änden. Det är skalet som tar utdata från det ena och lämnar vidare som indata till det andra. Om vi inte kände till kommandorör skulle vi kunna lösa samma uppgift så här: $ head stp.txt wc -w 41 får man t. ex. veta hur många ord det finns i de tio första raderna av filen stp.txt. Först utförs Tecknet : Tecknet kallas för lodstreck (vertical bar). Det skiljs egentligen från ett ovanligare tecken broken bar ( ), men på bland annat svenska tangentbord finns bara det ena, och det brukar då visas som på tangentbordet trots att tangenten faktiskt genererar. Tecknet behöver skrivas med AltGr. Förutom dess användning som pipe i Unix används tecknet också bland annat ofta för att ange alternativ i flera syntaxer och programspråk. $ head stp.txt >början $ wc -w början 41 början $ rm början Jaha, 41 ord! Här sparar vi undan resultatet av första steget i en fil (som här fick heta början, men den kunde förstås ha hetat nåt annat). När vi väl har räknat orden i den filen så behövs den inte längre, så vi tog bort den efteråt med rm. Kommandorör är bättre genom att mellanresultat inte behöver sparas i några filer utan kan skickas direkt från kommando till kommando. Observera att wc i kommandoröret inte har några argument! (Bara en väljare -w.) Alltid tidigare har vi använt det kommandot med filnamn som argument, och då räknar den ord eller rader i de filerna. Om den inte får några argument räknar den istället 31
3. MER OM SKALET FEL! i standard input. Ett vanligt fel är att blanda ihop detta och skriva nåt i stil med $ head stp.txt wc -w stp.txt Här har man gett ett argument till wc (nämligen»stp.txt«), så alltså läser den från den filen och inte från standard input. Så allt det som står före lodstrecket spelar ingen roll. 3.2 En användning av echo Kommandorör är ett sådant fall där kommandot echo kan vara användbart, för att ge en viss specifik indata till ett kommando. Antag att vi vill pröva hur wc egentligen räknar ord. Skulle den räkna»och/eller«som ett eller två ord? Ett sätt skulle förstås vara att skriva texten»och/eller«i en fil först, men vi behöver inte göra det, utan kan ge en bestämd text direkt som indata. $ echo och/eller wc -w 1 3.3 Omdirigering av standard input (<) Som en omvändning till > kan man använda < för att visa varifrån indata till ett kommando ska hämtas. Exempel: $ wc -w <början 41 Här hämtar skalet texten i filen början och lämnar den texten som indata till wc -w som tar fram antal ord i detta. Detta är inte alls lika vanligt att man använder som >. Det går ju nämligen lika bra att skriva bara 32 wc -w början istället, utan <-tecknet, eftersom wc liksom de flesta kommandon som man vill ge text som indata till också accepterar filnamn som argument och då själv läser in dessa filer som indata. Precis som det normala för standard output om man inte säger något är att det skickas till terminalen så är det normala för standard input att om man inte säger något så läses det från terminalen! Så om man skriver bara head får man ingen ny prompt direkt, utan skalet börjar läsa in textrader som man skriver in på terminalen. 1 Standard output och standard input förkortas ibland till stdout respektive stdin. Flera kommandon som vi sett tidigare som tar filnamn som argument och som läser sin input från dessa läser input från standard input istället om de inte får några argument. Det gäller bl. a. head, tail och wc. 3.4 Långa rör och filter En kommandorad kan innehålla godtyckligt många rör. I en fyrdelad kommandorad som aaa bbb ccc ddd kommer programmet aaa att lämna vidare sitt resultat till programmet bbb som lämnar vidare sitt resultat till programmet ccc som lämnar vidare sitt resultat till programmet ddd. I detta exempel läser bara aaa indata från standard input och ddd skriver utdata till standard output. Till detta kan man även lägga till omdirigering med < och >. Med en kommandorad som aaa <infil bbb ccc ddd >utfil läser det första steget aaa sin indata från filen infil och det sista steget ddd skriver slutliga utdata till filen utfil. Det är inte meningsfullt att skjuta in < eller > någonstans i mitten av en sånt här kommandorör. Symbolen visar ju redan varifrån indata ska tas och vart utdata ska skickas. 2 Ett kommando som läser in något från standard input, gör nånting med det, och sedan skriver ut det i modifierad form på standard output kallas ofta ett filter. 1 Sådan text som man skriver in kan man avsluta med Control-d. 2 Man kan även skriva <infil aaa istället för aaa <infil vilket kanske gör det tydligare.
3.6. Skalkommandot cut 3.5 Relativa sökvägar I avsnitt 1.3 såg vi hur fullständiga sökvägar kan användas för att beteckna en fil eller katalog. Sådana sökvägar kan alltid skrivas som argument till kommandon som ska ha filnamn eller katalognamn som argument. De fullständiga sökvägarna börjar alltid med / och har oftast flera / i namnet. Oftast anger man istället ett kortare namn på filer och kataloger. Det enklaste fallet är när dessa filer och kataloger ligger i det som är ens aktuella katalog. Då räcker det med att bara skriva namnet, som README eller kvack.png. Men om Ellen som exempel har sin hemkatalog /home/stp09/ ellen som aktuell katalog och vill referera till sin fil med ett slottsfotografi (se figur 1.3 på s. 5) vars fullständiga namn är /home/stp09/ellen/ fotografier/slottet.jpg så räcker det inte med bara slottet.jpg eftersom den filen inte ligger i samma katalog. Ett sätt är förstås att först byta katalog, men ett annat är att skriva en relativ sökväg som utgår från ens aktuella katalog. Det skulle i det fallet bli fotografier/slottet.jpg. Om man istället har /home/stp09 som aktuell katalog kan man skriva ellen/fotografier/ slottet.jpg. Alla sådana namn som inte börjar med / (eller ~) utgår från aktuell katalog. För att röra sig uppåt i filträdet använder man den särskilda beteckningen.. som finns i varje katalog och pekar till den katalogens föräldrakatalog. Om Ellen har sin underkatalog Desktop som aktuell katalog kan hon t. ex. skriva.. för att referera till sin hemkatalog och../fotografier/slottet.jpg för att referera till det där fotografiet. En användning av.. har du redan sett: cd.. för att gå upp ett steg. Fullständiga sökvägar börjar alltså med / och utgår från roten (som ju betecknas /). Övriga sökvägar är relativa och utgår från aktuell katalog. En tilde (~) i början av sökvägar är bara ett förkortat skrivsätt för något som börjar med /home, så sådana sökvägar är också fullständiga. Förutom.. för föräldrakatalogen finns även. i varje katalog och betecknar just den katalogen. Det betyder alltså samma sak att skriva fotografier/ slottet.jpg och t. ex../fotografier/slottet. jpg eller fotografier/./slottet.jpg. Trots att dessa. och.. finns i varje katalog så syns de normalt inte. Det är helt enkelt eftersom de börjar med punkt och alltså är dolda. 3.6 Skalkommandot cut Kommandot cut klipper i sin indata så att bara vissa delar av varje rad kommer med i utdata. Det är vanligt att använda detta kommando för textfiler som innehåller flera kolumner, normalt avgränsade av ett speciellt tecken TAB (tabulatur). 3 Med väljaren -f med ett tal som argument kan man då klippa ut bara någon av dessa kolumner. $ cat knattarna.txt Knatte Fnatte Tjatte Ole Dole Doffen Rip Rap Rup $ cut -f 1 knattarna.txt Knatte Ole Rip $ cut -f 2 knattarna.txt Fnatte Dole Rap Det går också att klippa ut flera kolumner tillsammans, som t. ex. cut -f 2-3 för kolumn 2 och 3. 3.7 TAB I textfiler visas TAB-tecken som ett hopp fram till nästa tabulatorposition, och dessa ligger normalt med åtta stegs mellanrum. Det är alltså bara ett tecken i filen, även om det ser ut som mer. När man editerar text används TAB-tangenten för att göra ett»lagom långt«indrag, vilket kanske är ett TAB-tecken, men kanske längre, och kanske bara nåt enstaka mellanslag, beroende på vad det är för slags text och hur omgivningen ser ut. Det är alltså inte alls alltid så att det verkligen blir ett TABtecken i en fil för att man trycker på den tangenten. Den tangenten används ju dessutom även till annat. Vi har t. ex. använt den mycket till komplettering, och den används också ofta för att växla mellan olika inmatningsfält. 3 I avsnitt 3.7 står det mer om detta mystiska tecken! 33
3. MER OM SKALET $ head --help Usage: head [OPTION]... [FILE]... Print the first 10 lines of each FILE to standard output. With more than one FILE, precede each with a header giving the file name. With no FILE, or when FILE is -, read standard input. Mandatory arguments to long options are mandatory for short options too. -c, --bytes=[-]n print the first N bytes of each file; with the leading `-', print all but the last N bytes of each file -n, --lines=[-]n print the first N lines instead of the first 10; with the leading `-', print all but the last N lines of each file -q, --quiet, --silent never print headers giving file names -v, --verbose always print headers giving file names --help display this help and exit --version output version information and exit N may have a multiplier suffix: b 512, k 1024, m 1024*1024. Report bugs to <bug-coreutils@gnu.org>. Figur 3.1: Hjälptexten för head. 3.8 Att tolka hjälp om skalkommandon Som vi sett så har många program en väljare --help som ger en hjälptext om det kommandot. Den hjälptexten är skriven rätt kompakt och kräver att man är van för att veta hur den ska tolkas. I figur 3.1 ges ett exempel, med hjälptexten för head. Först kommer en usage-rad som sammanfattning. Det visar att det som vanligt kan komma ett antal väljare ([OPTIONS]...) och att det sedan kan följa ett antal argument som är filnamn ([FILE]...). Hakparenteserna visar att det är en optionell del som inte behöver vara med. Punkterna visar att det får finnas flera sådana. Man kan jämföra med motsvarande rad för grep som lyder Usage: grep [OPTION]... PATTERN [FILE]... Här står det första argumentet,»pattern«, texten som man ska söka efter, inte inom hakparenteser, så det argumentet måste alltid finnas med. 4 Däremot behöver inte några filnamn finnas med. 4 Att det första argumentet kallas för»pattern«är för att det Det kan också finnas flera alternativa sätt att köra ett program. Kommandot cp som kopierar filer kan t. ex. anropas på dessa två olika sätt: 5 Usage: cp [OPTION]... SOURCE DEST or: cp [OPTION]... SOURCE... DIRECTORY Den första raden beskriver hur man använder cp med två argument, t. ex. cp foo.ogg bar.ogg för att kopiera filen foo.ogg till bar.ogg. I den andra versionen kan det finnas flera»source«(eftersom det står punkter efter) och sista argument måste vara ett namn på en katalog. Det betyder att kopiera allt man räknar upp som en»source«till den katalogen. (Kommandot mv (move) kan man anropa på precis samma sätt för att byta namn på eller flytta på filer.) I beskrivningen som följer i figur 3.1 beskrivs närmare hur de olika argumenten tolkas. Här står bland annat att om man inte har angivit någon FILE så ska inte behöver vara en fix text, utan kan vara ett mönster som man söker efter. Detta tas upp senare. 5 Detta är en vit lögn. Det finns faktiskt ett tredje sätt också, och det första sättet har en extra optionell väljare, men det spelar ingen roll nu. 34
3.8. Att tolka hjälp om skalkommandon kommandot»read standard input«istället. Så beter sig många kommandon som man kan ge filnamn som argument. Större delen av beskrivningen är en lista med olika väljare som kommandot tar. Här listas synonyma väljare tillsammans. T. ex. betyder head -q, head --quiet och head --silent detsamma. Vilka argument som ska ha argument framgår också. Då det står --lines=[-]n så ska tydligen --lines ha ett argument, och därmed även dess synonym -n. Värdet för den väljaren skrivs här som [-]N och tydligen ska N här ska vara ett tal. Hakparenteserna betyder som på andra ställen nånting som kan vara med men inte behöver vara med. Så argumentet är antingen ett minustecken följt av ett tal eller också bara ett tal. Så man kan alltså skriva t. ex. head --lines=17 och head --lines=-3. Alla detaljer i hur head kan anropas är inte viktiga, utan det viktiga är här hur olika saker betecknas eftersom ni kan behöva kunna tolka sådana här beskrivningar själv. Framförallt gäller det att kunna plocka ut just den information man själv behöver. Om t. ex. några väljare eller varianter verkar helt obegripliga så behöver inte det göra något så länge man inte behöver dem. 35
Laboration 3: Mer om skalet Redovisning Skicka ett mail till Per med svar på frågorna Skicka mailet senast tisdagen den 15/9 och eventuella kompletteringar innan den veckan är slut. Om du har fått mail angående uppgifter på förra labben så svara på det separat istället för att skriva ett mail om alltihop! Det underlättar mycket för min rättning om mail om olika labbar ligger i olika mail. Det var en gång... Gå till kurskatalogen. Där ska bland annat din saga.txt från s. 26 finnas. Uppgift 3.1 Ge ett kommando som tar fram de tre första raderna av din saga. Uppgift 3.2 Ge ett kommando som räknar hur många ord det finns i de tre första raderna av din saga. I uppgift 2.28 skapade du en fil saga40.txt som innehåller samma text som saga.txt, men omformatterad så att radlängden är max 40. I uppgift 2.29 stod att den borde ha fått färre rader än saga.txt, men det stämmer ju inte! Med så korta rader borde det istället ha blivit fler rader. Uppgift 3.3 Ge ett kommando som räknar hur många rader det är i saga40.txt. Uppgift 3.4 Om du inte hade den där filen saga40.txt hur skulle du då (utan att skapa en sådan fil som mellanresultat) ta reda på hur många rader din saga.txt skulle få om den bröts om till att få så korta rader? Uppgift 3.5 Ge ett kommando som tar fram den näst första raden i din saga. Från begabba till utströ Filen /local/kurs/ids/verb.txt innehåller en lista med svenska verb från Den stora svenska ordlistan. 6 I denna fil har de baklängessorterats, dvs. sorterats efter slutet på orden. (Det innebär att rimord tenderar att hamna efter varann.) Kopiera den till din kurskatalog. Uppgift 3.6 Ge ett kommando för att räkna rader och ord i den där filen. (Det ska ligga ett ord per rad, så det borde vara lika många ord som rader.) Uppgift 3.7 Ge ett kommando som talar om vilka verb där som innehåller»vv«(som t. ex.»avvisa«). Uppgift 3.8 Ge ett kommando som kombinerar ovanstående i ett kommandorör med ett kommando som räknar rader så att du får fram hur många verb som innehåller»vv«. Uppgift 3.9 Ge ett kortare kommando som gör samma sak som förra uppgiften genom att använda en lämplig väljare till sökkommandot. Därmed behövs inget kommandorör. Uppgift 3.10 Ge ett kommando som listar vilka av de tio första verben i listan som innehåller bokstaven v. Uppgift 3.11 Ge ett kommando som listar de första tio verben i listan som innehåller bokstaven v. 6 En fri svensk ordlista, tillgänglig på http://dsso.se/, version 1.29. 36
Delstater Tycker du att de två föregående uppgifterna är likadana har du inte läst tillräckligt noga! Kommandona och deras resultat skiljer sig åt. Uppgift 3.12 Ge ett kommando som listar vilka verb som innehåller såväl bokstaven j som bokstaven y. Google Translate Ge kommandot gtrans -t sv 'To be or not to be' som översätter sitt argument med hjälp av Google Translate på webben. (Detta är inte ett standardprogram utan något som Per lagt upp för denna labb.) Med väljaren -t som tar ett argument (här»sv«) talar man om till vilket språk det ska översättas. Några av de språkkoder som finns nämns i tabell 3.1 (men Google Translate klarar inte alla dessa språk). Läs hjälptexten med gtrans --help. Uppgift 3.13 Ge ett kommando som översätter»det går som en dans.«till engelska. Ange vilket resultat du får också. Tabell 3.1: Språkkoder enligt standarden ISO 639-1 för några språk med många talare i världen, Europa, Norden eller Sverige sq ar bn nb bs bg da en fi fr el hi is it ja yi zh xy ku albanska arabiska bengali bokmål bosniska bulgariska danska engelska finska franska grekiska hindi isländska italienska japanska jiddisch kinesiska kroatiska kurdiska nl se no nn fa pl pt ro ru sr so es sv cs tr de uk hu be nederländska nordsamiska norska nynorska persiska polska portugisiska rumänska ryska serbiska somaliska spanska svenska tjeckiska turkiska tyska ukrainska ungerska vitryska Uppgift 3.14 Ge ett kommando som översätter någon meningen, t. ex.»det var en afton i början av maj.«, från svenska till tyska. Ange vilket resultat du får också. I hjälptexten står att om man inte anger någon text så kommer programmet att»read standard input«. Ge ett kommando som översätter din saga till något valfritt språk med alfabetisk skrift. Resultatet blir en väldigt lång rad. Gör ett kommandorör där du kombinerar det kommando du nyss gav med fmt för att formattera om till kortare rader. Uppgift 3.15 Hur lyder nu hela ditt kommando och det resultat det ger? Uppgift 3.16 Skriv ett kommandorör med två delar. Första delen ska översätta»smått och gott«till danska och den andra delen ska översätta resultatet tillbaka till svenska igen! Ange hela kommandoraden och vad det blir för resultat. Uppgift 3.17 Översätt din saga till kinesiska och tillbaka i en enda kommandorad. Delstater I filen /local/kurs/ids/us-states.txt finns en lista över USA:s delstater tillsammans med datum då de ratifierade USA:s konstitution eller kom med i unionen. 7 Kopiera den till din kurskatalog och titta på den i Emacs. Den är sorterad efter datumet. Tryck C-s (för sökning) och sen TAB för att söka efter TAB-tecken. Gå även fram och bak tecken för tecken (med <right> och <left> eller C-f och C-b) så märker du också att det bara är ett tecken mellan datumet och namnet. Uppgift 3.18 Ge ett skalkommando som bara listar raderna för de delstater som kom med i USA på 1850-talet. Uppgift 3.19 Ge ett kommando som klipper ut bara delstaternas namn. Uppgift 3.20 Ge ett kommando som skriver ut alla delstater (utan datum) som har»new«med i sitt namn. 7 Enligt http://en.wikipedia.org/wiki/u.s._state. 37
LABORATION 3: MER OM SKALET Uppgift 3.21 Ge ett kommando som skriver ut alla delstater (utan datum) som har ett mellanrum med i sitt namn. Kommandot sort är ett filter som sorterar de rader det får in i alfabetisk ordning och skriver ut resultatet. Uppgift 3.22 Ge ett kommando som skriver ut bara deltstaternas namn, sorterade i alfabetisk ordning. Uppgift 3.23 Ge ett kommando som skriver ut de tretton ursprungliga delstaterna (dvs. de tretton första i listan), sorterade i alfabetisk ordning. Uppgift 3.24 Ge ett kommando som skriver ut vilken delstat som kommer sist i alfabetisk ordning. Röda rummet Filen /local/kurs/ids/rummet.txt innehåller början av August Strindbergs roman Röda rummet. Filen rummet.words i samma katalog innehåller samma text, men med ett ord per rad tillsammans med ordklassangivelse. Titta på den i Emacs! (Interpunktion som,.;:?! räknas här som egna ord med ordklassen»punkt«kort för interpunktion.) Kopiera dessa två till din labbkatalog. Uppgift 3.25 Kolumnen med ordklass verkar hoppa lite och stå olika långt till höger för olika ord. Hur kommer det sig? Uppgift 3.26 Ge ett kommando för att spara en sorterad lista av rummet.words i en ny fil rummet. sorted. Uppgift 3.27 Se efter hur sorteringen har blivit. Är det nåt anmärkningsvärt med den? (Vi återkommer till olika slags sortering senare.) Uppgift 3.28 Ge ett kommando som bara plockar ut ordklasserna från rummet.words och sparar dessa sorterade i en fil rummet.ordklasser. (Det borde bli många rader efter varandra som är likadana där, t. ex. många rader som det bara står»subst«på.) Uppgift 3.29 Ge ett kommando som talar om hur långt det längsta ordet i rummet.words är. (Bara själva ordet ska mätas, utan dess ordklassmarkör.) Uppgift 3.30 Ge ett kommando som översätter de tre första raderna i rummet.txt till japanska. Gott och blandat Skriv cd alice för att gå ner till den underkatalog som du skapade i uppgift 1.5. 8 Uppgift 3.31 Om du nu utan att byta katalog vill lista innehållet i din kurskatalog i skalet, hur skriver du då? Uppgift 3.32 Och vad ger du för kommando för att kopiera cheshire-cat.jpg där till din kurskatalog? Uppgift 3.33 Vilka av följande sökvägar är absoluta, och vilka är relativa? a) /local/texts/jabberwocky b) ~/korpus.txt c) bar.txt d) ~starback/exempel.txt e) inte/mitt/bord f)../filnamn g) ~ellen Uppgift 3.34 Hur många argument ges till kommandot i dessa exempel? a) mv foo.txt bar.txt ~/Desktop b) sort korpus20.txt c) echo I am a donkey. d) echo 'I am a donkey.' e) tail -n 3 Min fil.txt När ni börjar komma in i att använda kommandorör så börjar ni kanske skriva sånt som cat saga.txt head -n 1 för att ta fram första raden i din saga. Men det är ju alldeles onödigt! Här behövs inget kommandorör. Uppgift 3.35 Hur skriver man istället som är kortare, vackrare och enklare? Med kommandot xpdf kan du titta på en PDFfil. 9 Som argument ska det få filnamnet och man kan använda väljaren -z med argument för att tala om vilken zoom man vill använda i procent där argumentet 100 betyder 72 dpi (dots per inch). 8 En del kallade den för Alice istället, med versalt A. 9 PDF (Portable Document Format) är ett populärt filformat utvecklat av Adobe Systems. 38
Gott och blandat Uppgift 3.36 Tyvärr beter sig program lite olika åt när de ska tolka sina väljare. Ibland kan det vara mellanslag mellan en väljare och dess argument ibland inte. Hur är det för xpdf? Uppgift 3.37 Hur ser kommandot ut för att titta på filen /local/kurs/ids/ids2.pdf med 90 % zoom? Kör detta kommando för att se på detta kapitel i kurskompendiet. Observera att du inte får någon ny prompt i terminalen förrän du avslutar xpdf! Det är det normala i skalet att endast ett program i taget utförs. (När du kör xpdf får du en varning i terminalen. Den kan du ignorera.) För att köra en Emacs från skalet skriver man helt enkelt emacs. Det kommandot kan man ta fram hjälptexten för med samma väljare som vi sett för andra kommandon. Uppgift 3.38 Ge ett skalkommando som översätter de sista fem raderna av den hjälptexten till japanska! Ange även vad du fick för resultat. Uppgift 3.39 Hur kan du med ett skalkommando skapa en fil foo.txt i vilken det står»blahonga«? 39