lu.se

Datavetenskap

Lunds Tekniska Högskola

Denna sida på svenska This page in English

Terminal

Datorhistorien

UNIX-historia

Operativsystemet


Exempel #1

Problem

Jag vill kompilera och köra mitt java-program i Terminalen

Lösning

  1. Hämta ner zip-filen och packa upp den

    unzip squares.zip
  2. Gå ner i katalogen:
    
cd squares
  3. Titta på filens innehåll:

    less SquareBonanza.java
  4. Kompilera alla java-filer:
    
javac *.java
  5. Kontrollera att det finns en kompilerad .class-fil:

    ls -ls
  6. Kör den:

    java SquareBonanza

 


Exempel #2

Problem

Ett antal kataloger i ett filträd saknade filen ”start.txt”. 

Man kan lösa detta en katalog i taget, men det är manuellt arbetskrävande (och tråkigt)

Lösning

Skriv en for-loop i bash och lös det direkt:

for i in $(find . -type d)
find . -type d)
# ’i’ kan se ut så här: ’./servers/fyra_fem/dokumentation’
do   if [ ! -f "$i/start.txt" ]; then
    echo "===== $(basename $i) =====" > ”${i}/start.txt"
    chown _www:_www $i
  fi
done

 


Exempel #3

Problem

Jag blev inte nöjd med filerna i förra exemplet och vill ta bort allihopa. 

Lösning

Hitta dem med find och radera dem direkt:

find . -name start.txt -exec rm -rf {} \;

Om jag i stället vill ändra rättigheterna på filerna så att alla får läsa filen gör man så här:

find . -name start.txt -exec chmod ugo+r {} \;

(u=user, g=group, o=other; r= read)


Exempel #4

Problem

Jag vet att en av mina filer innehåller texten ”Blittan Blattan”. Var finns filen?

Lösning

Leta i filinnehållet med grep:
grep -r "Blittan Blattan"

*På OS X kan man använda kommandot mdfind:
mdfind "Blittan Blattan"

 

Problem

Jag vet att jag har en fil som heter  något med XYZ

Lösning

Leta i filinnehållet med find:
find . -name *XYZ*
(söker i befintlig katalog och nedåt i filträdet)

Alternativt kan man använda locate:
locate XYZ
(söker i hela filsystemet)


Exempel #5

Problem:

Jag kan inte avmontera en USB-tumme – något program ”håller” den. Vilket?

Lösning

Använd kommandot lsof:
lsof | grep /Volumes/tumme

 

Problem

Mitt program skriver något i en fil, men jag vet inte vilken!

Lösning

Använd lsof för att ta reda på vilka filet mitt program har öppna:
lsof -p $(pgrep "Programnamn")


Exempel #6

Problem:

Jag undrar vilka datorer min dator kommunicerar med!

Lösning

Använd lsof för att se vilka program som lyssnar (”LISTEN”) eller har en förbindelse igång (”ESTABLISHED”):
lsof -i4 | egrep "LISTEN|ESTABLISHED"

Kör du detta som dig själv kan du endast se dina egna förbindelser. Kör det som root i stället för att se alla förbindelser!


Exempel #7

Problem:

Jag vill köra backup automatiskt hemifrån mot en dator på jobbet, utan att betala något för det

Lösning

Använd kommandot rsync och gör hela backupkörningen i en enda rad (”oneliner”):
ssh -p 22 computer.cs.lth.se 'echo "password" | hdiutil attach /Volumes/Backup/Privat_backup.sparseimage -nobrowse' >& /dev/null ; /usr/local/bin/rsync -aNHAXxv --protect-args --fileflags --force-change --rsync-path="/usr/local/bin/rsync" /Users computer.cs.lth.se:/Volumes/Privat_backup/Users | tail -n 3 | grep bytes | /Users/peterm/bin/sendEmail -f <mailto:Peter.Moller@comhem.se> Peter.Moller@comhem.se<mailto:Peter.Moller@comhem.se> -t <mailto:Peter.M@me.com> Peter.M@me.com<mailto:Peter.M@me.com> -u Backuprapport -s mail1.comhem.se  -xu user -xp password ; ssh -p 22 computer.cs.lth.se hdiutil detach /Volumes/Privat_backup -quiet

Förklaring:

  1. Koppla upp mot min dator på jobbet (använder sparad ssh-nyckel) och montera den krypterade och lösenordsskyddade disk-imagen där backupen skall läggas
  2. Kör rsync från min /Users till denna disk (med verbose på)
  3. Ta en rad från utskriften på rsync och skicka till min mailadress så att jag får reda på att något har hänt
  4. Koppla upp mig igen och avmontera disk-imagen

Exempel #8

 


Exempel #9

Problem:

Jag har en liggfil från en webbserver (Apache) och jag är nyfiken på varifrån (land och stad) anropen kommer

Lösning

Tag ut IP-adresserna från loggfilen och lägg i en fil (exempel finns här):

less /var/log/apache2/access_log | grep "09/Feb/2016" | awk '{print $2}' | egrep -v "::1" | uniq > moodle_9_feb.txt

Använd följande funktion (förutsätter en nyckel som man skaffar här samt en fil med landsnamn, ”Countries.txt”, som skall ligga i samma katalog. Den finns här):

# Do the Geo Lookup (if key exists)
# Assumes:
# - $1: IP
# curl 'http://api.db-ip.com/addrinfo?addr=68.169.130.16&api_key=123456789123456789'
# Gives:
# - $Country: Country Name
# - $City: City Name
function GeoLookup ()
{
 # Skaffa nyckel på https://db-ip.com/api/free och skriv in som ”GeoLookupKey” på nästa rad
 GeoLookupKey="xxxxxxxxxxx"
 GeoLookupURL="http://api.db-ip.com/addrinfo?addr="
 Countries="Countries.txt"
 IP_to_check="$1"
 Rad="$(curl -s "$GeoLookupURL$IP_to_check&api_key=$GeoLookupKey")"
 # -> Rad='{"address":"78.69.30.61","country":"SE","stateprov":"Stockholm County","city":"Farsta"}'
 # Simple sanity check: count the number of qoutation marks (should be 16)
 if [ "$(echo $Rad | grep -o '"' | wc -w | awk '{print $1}')" -eq 16 ]; then
   City="$(echo $Rad | cut -d\" -f 16)"
   Country="$(grep $(echo $Rad | cut -d\" -f 8) $Countries | cut -d: -f2)"
 else
   City="look up"
   Country="Could not"
 fi
 # Skriv ut
 echo "$IP_to_check ($(host $IP_to_check | awk '{print $NF}')) is located in \"$City\" in \"$Country\""
}

Kör sedan en loop på detta:

$ exec 6<moodle_9_feb.txt
$ while read -u 6 IP
do
GeoLookup $IP
done

Man får då följande utskrift:

74.91.28.62 (3(NXDOMAIN)) is located in "North Kansas City (501)" in "United States"
84.55.117.198 (84-55-117-198.customers.ownit.se.) is located in "Stockholm" in "Sweden"
78.67.82.13 (78-67-82-13-no251.tbcn.telia.com.) is located in "Link\u00f6ping" in "Sweden"
213.80.99.215 (c215.a99.sto.bahnhof.net.) is located in "Stockholm" in "Sweden"
180.76.15.22 (baiduspider-180-76-15-22.crawl.baidu.com.) is located in "Beijing" in "China"
31.208.75.41 (dynamic.1.6.34dbfd72680.305a3a712940.cust.bredband2.com.) is located in "Lund" in "Sweden"
208.115.113.88 (3(NXDOMAIN)) is located in "Seattle (Riverton-Boulevard Park)" in "United States"
84.219.150.17 (c-1196db54.016-114-6c756e10.cust.bredbandsbolaget.se.) is located in "Karlskrona" in "Sweden"
180.76.15.148 (baiduspider-180-76-15-148.crawl.baidu.com.) is located in "Beijing" in "China"
180.76.15.5 (baiduspider-180-76-15-5.crawl.baidu.com.) is located in "Beijing" in "China"
180.76.15.157 (baiduspider-180-76-15-157.crawl.baidu.com.) is located in "Beijing" in "China"
83.185.89.238 (m83-185-89-238.cust.tele2.se.) is located in "Ystad" in "Sweden"

 


UNIX-filosofin

  • Skriv program som gör en sak och gör den väl
  • Skriv program som fungerar tillsammans
  • Skriv program som arbetar med textströmmar, för det är ett universellt interface

Doug McIlroy


Filsystem


Processer

  • UNIX har en familjelik processmodell: endast en existerande process kan skapa en ny process (förälder- och barn-process). Detta ger ett familjeträd av relaterade processer
  • Ett barn kan inte ha högre rättigheter än sin förälder: den första processen som startas vid systemstart är ”gud” (init på Linux, launchd på OS X)
  • Alla processer har: standard-in, standard-out, standard-err som alla är av typen text
  • Man skapar en process genom att starta ett program (eller terminalkommando)
  • Man övervakar processer med kommandot ps
  • Man pausar, startar, stänger av processer o.s.v. med kommandot kill (TERM, SIGSTOP, SIGCONT, KILL m.m.)

Pipe


Variabler

 

  • Skalet är programmerbart: alla vanliga konstruktioner finns (lopar, if-satser, funktioner o.s.v.) och även variabler
  • Systemet definierar ett antal variabler – användaren kan definiera ytterligare efter sina egna behov
  • Variabler är typlösa och kan konverteras efter behov
  • Sätt variabler med: export VAR="Mitt värde"
  • Här en tabell över några vanliga variabler från systemet:
    VariabelFörklaringExempel
    $PATHUppräkning över var binärer finns /usr/local/jdk/bin:/usr/local/bin:/usr/local/bin/X11
    $SHELLVilket skal man kör/bin/zsh
    $PWDVilken katalog befinner jag mig i?/h/d2/b/peterm
    $EDITORVilken är min default-editor?EDITOR=vi
    $LANGVad är det för språkinställning?LANG=sv_SE.UTF-8
    $0Det körande scriptets hela rad/usr/bin/open_ports.sh -u
    $$Körande processnumret83975
    $?Resultat från senaste kommando0
    $PS1Promptens definition\e[37;41m\d \t ▶ \u@\h:\w$ \e[0m \[\e];\u@\h:\w\a\]

Ägare

  • Alla processer och alla filer har en ägare
  • Ägaren tillhör en grupp
  • Tre nivåer finns: ägare (u), grupp (g), andra (o)
  • För varje nivå finns i filsystemet tre rättigheter:
    läsa (r), skriva (w), köra (x)

Titta på körande processer:
login{peterm}: ps aux | grep "[v]i "
peterm 17642 0.1 0.1 240328 10324 pts/43 Sl+ 12:26 0:00 vi .profile

Titta på filer:
login{peterm}: ls -ls .profile
4 -rwx--x--x 1 peterm cs 3732 Jan 21 12:27 .profile*


Hjälp

Man får hjälp med kommandona med kommandot man: man ls visar manualsidan för hur man listar filer.

Alla kommandon har optioner. Exempelvis gör ”-lst” till kommandot ls att filerna visas i en lång listning men den nyaste överst och storleken uttryckt i kByte.

De flesta kommandon är s.k. POSIX-kompatibla och då kan man skriva optionerna i vilken ordning som helst.

Dessa webbsiter är bra att besöka:

http://stackoverflow.com

http://superuser.com

http://www.commandlinefu.com

Introduction to the Unix shell history

System Architecture

File System Hierarchy Standard

UNIX – Special Variables

 

O'Reilley är ett förlag med många goda böcker i sitt sortiment. Här kan nämnas:

http://www.tutorialspoint.com/unix/unix-special-variables.htmLearning the Bash Shell (3rd edition)

The Linux Command Line

Learning Shell Scripting with Zsh


Kuser

Jag kan itne gå i god för hur bra dessa kurser är, men här är några:

http://www.lynda.com/Bash-training-tutorials/1804-0.html

https://linuxacademy.com/courses/index/course/course/15

https://www.udemy.com/draft/34409/

http://wiki.bash-hackers.org/scripting/tutoriallist

 


Nackdelar??

Konstruktionen med pipe gör kommandomiljön mycket kraftfull!

MEN! Kommandona är ofta kryptiska fungerar enligt paradigmet ”Remember-and-type”. Det finns många hundratals kommandon i ett normalt UNIX-system och det är en utmaning att minnas dem!

Vill man se alla kommandon som finns [i ens PATH] men en kort förklaring kan man köra följande kommandosekvens [i Linux]:
echo -n $PATH | xargs -d : -I {} find {} -maxdepth 1 -executable -type f -printf '%P\n' | sort -u | xargs whatis 2> /dev/null | egrep '\((1|1m|6|8)\)'

För OS X kör man detta:
echo ${PATH//:/ } | xargs -J % find % -maxdepth 1 \( -type f -or -type l \) | xargs basename | sort -u | xargs whatis 2> /dev/null | egrep '\((1|1m|6|8)\)'