Terminal
Datorhistorien
UNIX-historia
Operativsystemet
Exempel #1
Problem
Jag vill kompilera och köra mitt java-program i Terminalen
Lösning
- Hämta ner zip-filen och packa upp den
unzip squares.zip
- Gå ner i katalogen:
cd squares
- Titta på filens innehåll:
less SquareBonanza.java
- Kompilera alla java-filer:
javac *.java
- Kontrollera att det finns en kompilerad .class-fil:
ls -ls
- 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:
- 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
- Kör rsync från min /Users till denna disk (med verbose på)
- 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
- 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:
Variabel Förklaring Exempel $PATH Uppräkning över var binärer finns /usr/local/jdk/bin:/usr/local/bin:/usr/local/bin/X11
$SHELL Vilket skal man kör /bin/zsh
$PWD Vilken katalog befinner jag mig i? /h/d2/b/peterm
$EDITOR Vilken är min default-editor? EDITOR=vi
$LANG Vad är det för språkinställning? LANG=sv_SE.UTF-8
$0 Det körande scriptets hela rad /usr/bin/open_ports.sh -u
$$ Körande processnumret 83975
$? Resultat från senaste kommando 0
$PS1 Promptens 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:
Introduction to the Unix shell history
File System Hierarchy Standard
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)
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)\)'