Skal och skriptning

Skalet är ett effektivt, textbaserat gränssnitt till din dator.

Skalprompten är det som möter dig när du öppnar en terminal. Den låter dig köra program och kommandon. Vanliga kommandon är:

Men skalet låter dig göra mycket mer. Du kan anropa vilket program som helst på datorn, och det finns kommandoradsverktyg för i princip allt du kan vilja göra. De är ofta effektivare än grafiska motsvarigheter. Vi går igenom många av dem i den här kursen.

Skalet erbjuder också ett interaktivt programmeringsspråk (“skriptning”). Det finns många skal:

I den här kursen fokuserar vi på de allmänt förekommande sh och bash, men prova gärna andra. Jag gillar fish.

Skalprogrammering är ett mycket användbart verktyg i din verktygslåda. Du kan antingen skriva program direkt i prompten, eller i en fil. #!/bin/sh + chmod +x gör ett skalskript körbart.

Arbeta med skalet

Kör ett kommando flera gånger:

for i in $(seq 1 5); do echo hello; done

Det finns mycket att packa upp här:

Vi har variabler:

for f in $(ls); do echo $f; done

Det skriver ut varje filnamn i aktuell katalog. Du kan också sätta variabler med = (ingen blanktecken):

foo=bar
echo $foo

Det finns också en mängd “specialvariabler”:

För att bara skriva ut kataloger:

for f in $(ls); do if test -d $f; then echo dir $f; fi; done

Här finns mer att packa upp:

Men vänta. Det här är fel. Vad händer om en fil heter “My Documents”?

Argumentsplittring

Bash delar argument på blanktecken, vilket inte alltid är det du vill.

Globbing är svaret.

Problem med blanktecken slutar inte där:

Komponerbarhet

Skalet är kraftfullt delvis tack vare komponerbarhet. Du kan kedja flera program i stället för att ha ett enda program som gör allt.

Nyckeltecknet är | (pipe).

Alla program du startar (“processer”) har tre “strömmar”:

Bash har också flera andra sätt att komponera program.

Du kan gruppera kommandon med (a; b) | tac. Det kör a, sedan b, och skickar all deras utdata till tac, som skriver ut indata i omvänd ordning.

Ett mindre känt men mycket användbart sätt är process substitution. b <(a) kör a, skapar ett temporärt filnamn för dess utström, och skickar det filnamnet till b. Till exempel:

diff <(journalctl -b -1 | head -n20) <(journalctl -b -2 | head -n20)

visar skillnaden mellan de första 20 raderna i senaste bootloggen och bootloggen före den.

Jobb- och processkontroll

Vad gör du om du vill köra långvariga saker i bakgrunden?

Vad gäller annan processaktivitet på datorn?

Flaggor

De flesta kommandoradsverktyg tar parametrar via flaggor. Flaggor finns oftast i kort form (-h) och lång form (--help). Vanligen ger CMD -h eller man CMD en lista över flaggor som programmet stöder. Korta flaggor kan oftast kombineras, så rm -r -f är samma som rm -rf eller rm -fr. Vissa vanliga flaggor är i praktiken en standard, och du ser dem i många program:

Ett dubbelt bindestreck -- används också i inbyggda kommandon och många andra kommandon för att markera slutet på kommandoalternativ, varefter endast positionsargument accepteras. Om du därför har en fil som heter -v (det går) och vill köra grep på den, fungerar grep pattern -- -v medan grep pattern -v inte gör det. Ett sätt att skapa en sådan fil är faktiskt touch -- -v.

Övningar

  1. Om du är helt ny i skalet kan du läsa en mer heltäckande guide, till exempel BashGuide. Om du vill ha en djupare introduktion är The Linux Command Line en bra resurs.

  2. PATH, which, type

    Vi pratade kort om att miljövariabeln PATH används för att hitta programmen du kör från kommandoraden. Låt oss utforska det lite mer.

    • Kör echo $PATH (eller echo $PATH | tr -s ':' '\n' för snyggare utskrift) och granska innehållet. Vilka sökvägar listas?
    • Kommandot which letar upp ett program i användarens PATH. Prova which för vanliga kommandon som echo, ls eller mv. Notera att which är lite begränsat eftersom det inte förstår skalalias. Testa type och command -v för samma kommandon. Hur skiljer sig utdata?
    • Kör PATH= och testa de tidigare kommandona igen. Vissa fungerar och vissa inte. Kan du lista ut varför?
  3. Specialvariabler
    • Till vad expanderar ~? Vad sägs om .? Och ..?
    • Vad gör variabeln $??
    • Vad gör variabeln $_?
    • Till vad expanderar !!? Och !!*? Och !l?
    • Leta upp dokumentation för dessa och bekanta dig med dem
  4. xargs

    Ibland fungerar piping inte riktigt, eftersom kommandot som tar emot data inte förväntar sig ett radseparerat format. Till exempel visar kommandot file egenskaper för en fil.

    Kör ls | file och ls | xargs file. Vad gör xargs?

  5. Shebang

    När du skriver ett skript kan du ange vilket program som ska tolka skriptet, via en shebang-rad. Skriv ett skript som heter hello med innehållet nedan, gör det körbart med chmod +x hello, och kör det sedan med ./hello. Ta därefter bort första raden och kör igen. Hur använder skalet den första raden?

       #! /usr/bin/python
    
       print("Hello World!")
    

    Du kommer ofta att se program med en shebang som ser ut så här: #! usr/bin/env bash. Det är en mer portabel lösning med egna för- och nackdelar. Hur skiljer sig env från which? Vilken miljövariabel använder env för att avgöra vilket program som ska köras?

  6. Pipes, process substitution, subshell

    Skapa ett skript som heter slow_seq.sh med innehållet nedan, och kör chmod +x slow_seq.sh för att göra det körbart.

       #! /usr/bin/env bash
    
       for i in $(seq 1 10); do
               echo $i;
               sleep 1;
       done
    

    Pipes (och process substitution) skiljer sig från att använda subshell-körning, alltså $(). Kör följande kommandon och observera skillnaderna:

    • ./slow_seq.sh | grep -P "[3-6]"
    • grep -P "[3-6]" <(./slow_seq.sh)
    • echo $(./slow_seq.sh) | grep -P "[3-6]"
  7. Övrigt
    • Kör touch {a,b}{a,b} och sedan ls. Vad dök upp?
    • Ibland vill du behålla STDIN och samtidigt skriva till fil. Kör echo HELLO | tee hello.txt.
    • Kör cat hello.txt > hello.txt. Vad tror du händer? Vad händer faktiskt?
    • Kör echo HELLO > hello.txt och sedan echo WORLD >> hello.txt. Vad innehåller hello.txt? Hur skiljer sig > från >>?
    • Kör printf "\e[38;5;81mfoo\e[0m\n". Hur blev utdata annorlunda? Om du vill veta mer, sök på ANSI color escape sequences.
    • Kör touch a.txt och sedan ^txt^log. Vad gjorde bash åt dig? Kör i samma anda fc. Vad gör det?
  8. Kortkommandon

    Precis som med alla program du använder ofta är det värt att lära sig kortkommandon. Skriv in följande och försök förstå vad de gör, och i vilka situationer de är praktiska. För vissa kan det vara enklast att söka online. (Kom ihåg att ^X betyder Ctrl+X.)

    • ^A, ^E
    • ^R
    • ^L
    • ^C, ^\ och ^D
    • ^U och ^Y

Edit this page.

Licensed under CC BY-NC-SA.