title: | Shell II: die kleinen Helferlein |
---|---|
Author: | Dario & Lars |
css: | https://wiki.hack-hro.de/talk_styles/assets/css/style2.css |
description: | Hackspace Rostock e.V. |
data-scale: | 0.7 |
data-transition-duration: | |
1 |
________ ________ / ______ \ / ______ \ / / \ \ / / \ \ / / \ " / \ \ | | \ / | | | | ____ _ " _ _ | | | | / ___|| |__ ___| | | | | | | \___ \| '_ \ / _ \ | | | | | | ___) | | | | __/ | | | | | | |____/|_| |_|\___|_|_| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Shell Workshop II
Ein Hoch auf die kleinen Helferlein!
Gestern, heute, morgen
- Rückblick (letzter Workshop): Shell steuert Prozesse, Eingaben, Ausgaben ...
- heute: kleine Programme, deren Funktionalitäten sich mit der Shell verknüpfen lassen
- Abschluss (nächster Workshop): Shell-Skripte - sauber und robust (inkl. Substitution & Quoting)
Fahrplan
- reguläre Ausdrücke (kleiner Exkurs)
- grep
- sed
- awk
- coreutils & Co.
Seid bereit!
- Startet eure Rechner
- Besucht http://pad.hack-hro.de/Shell2-Spass
- später werdet ihr es brauchen ...
Reguläre Ausdrücke
- reguläre Ausdrücke != globbing
- Implementierungen sind leicht verschieden
- Meta-Characters
Reguläre Ausdrücke - Beispiele
^foo
ba[rz]
hello (world|earth)!
grep
- Suche ein Muster in Textzeilen
- Anwendungen:
- Filterung
- Prüfung
- Dateisuche
grep - Beispiele
[t ]state DOWN[]
^[0-9]+(.[0-9]+){3}(/[0-9]+)?$
[[:space:]]IN[[:space:]]+SRV[[:space:]]+[[:digit:]]+[[:space:]]+[[:digit:]]
sed
- sed => 'stream editor'
- von '73 bis '74 von Lee E. McMahon in den Bell Labs entwickelt
- Nachfolger des '71 entwickelten, interaktiven Editors ed
- eines der frühesten Werkzeuge, das reguläre Ausdrücke interpretieren konnte
- arbeitet auf 'per Zeilen'-Basis
Haben wir auch das wichtigste nicht vergessen?
sed -n -e '/main[[:space:]]*(/,/^}/p' quelldatei.c | more
Grundlegende Kommandos (unvollständig)
- a - (append) fügt eine oder mehrere Zeilen an die passende Zeile an
- c - (change) ersetzt die ausgewählte Zeile durch eine (oder mehrere) neue
- d - (delete) löscht die passende Zeile
- i - (insert) fügt eine Zeile vor der Zeile ein auf die regex zutrifft
- l - (listing) zeigt nicht druckbare Zeichen an
- p - (print) gibt die Zeile aus
- r - (read) lese Zeilen aus Datei
- s - (substitute) ersetze Zeichenfolge in zutreffender Zeile durch eine andere
- w - (write) schreibe Zeilen in Datei
- ! - (Negation) wendet die Befehle auf die Zeilen an, auf die regex nicht zutrifft
Die Substiution von Zeichenfolgen
Das Substitutionskommando kann noch mit einigen Argumenten ergänzt werden:
- s/.../.../g - ersetze global (in jeder zutreffenden Zeile der Datei)
- s/.../.../p - drucke passende Zeilen auf stdout
- s/.../.../w - tausche Inhalt des Zwischenspeichers mit treffender Zeile
Viel verwendete Schalter für sed
- -n - schaltet die Ausgabe des Puffers (Patternspace) aus
- -e - führe mehrere Befehle nacheinander aus, Miniscript in der Kommandozeile ausführen
- -f - führe Datei (sed-script) aus
## sed -n -e 's/[[:space:]]$//' <datei..........leerzeichen am ende von Zeilen löschen
//etc/passwd Benutzernamen mit 'Benutzer' ersetzen (vll. auch Benutzer1, Benutzer2..)
awk
- Interpretierte Programmiersprache mit vielen Ähnlichkeiten zu C
- versteht die gleichen arithmetischen Operatoren wie C
- Verarbeitung von Zeichenketten
- kann man sich als "pseudo C-Interpreter" vorstellen
- in den 70ern entwickelt von A. Aho, B. W. Kernighan and P. Weinberger => Name, Bell Labs
Struktur eines awk-Programmes
muster { aktion }
- Die Schlüsselwörter BEGIN und END kennzeichnen einen Block von Anweisungen, der ausgeführt werden soll, bevor irgendwelche weiteren Zeilen gelesen werden
BEGIN { aktion }
{ noch eine aktion }
END { aktion }
- Feld-Operatoren werden in der Form $n, wobei n eine Zahl ist, geschrieben
ls -l | awk '{ print $9, "t", $3 }'
- speziell: $0 gibt das gesamte Feld zurück
Arithmetische Ausdrücke
+, -, *, /, %
Besonderheit: ein Leerzeichen bedeutet 'hänge die folgende Zeichenkette an'
Welcher Wert wird der Variablen x zugewiesen?
x=1+5*2 3
awk 'BEGIN { x=5+4 5; print x;}'
Zuweisungsoperatoren
+= Addiere Ergebnis zur Variablen
-= Subtrahiere Ergebnis von der Variablen
*= Multipliziere Variable mit dem Ergebnis
/= Teile Variable durch das Ergebnis
%= Modulo Variable durch Ergebnis
Relationale Operatoren
- == , != , > , >= , < , <=
Reguläre Ausdrücke
- ~ : trifft zu auf /regex/
- !~ : trifft nicht zu auf /regex/
Boolean
- && und ||
Unär
- !
AWK Kommandos
- if ( kondition ) [ else anweisung ]
- while ( kondition ) anweisung
- for ( ausdruck ; kondition ; ausdruck ) anweisung
- for ( variable in feld ) anweisung
- break
- continue
- { [ anweisung ] ...}
- variable=ausdruck
- print [ liste-von-ausdrücken ] [ > ausdruck ]
- printf format [ , liste-von-ausdrücken ] [ > ausdruck ]
- next
- exit
awk -F: '{ if ($2 == "") print $1 ": hat kein Passwort!" }' </etc/passwd
vordefinierte Variablen
Input Field Separator:
- Kommandozeile awk -F
- in einem Skript { FS=":"; }
- bash: IFS
- standardmäig Leerzeichen
OFS - Output Field Separator:
- Standard: Leerzeichen
NF - Number of Fields
NR - Number of Records
awk '{ s += $1; } END { print "Summe:", s, "durchschnittl.:", s/NR }' <daten
RS - Record Separator
ORS - Output Record Separator
FILENAME - aktueller Dateiname ( der Datei, die verarbeitet wird )
Kleinkram!
Einstieg: ls & nl
- ls: Inhalt von Verzeichnissen ausgeben
- nl: Zeilen nummerieren
Anknüpfungspunkte
ls -l | nl
- Aufgabe: den git-Commits eines Branches aufsteigende Nummern zuordnen
Einstieg: date & read
- date: Datum ausgeben; aktuellen Zeitstempel ermitteln
- read: Zeileninhalt in Variable(n) übertragen
Für das Protokoll
(
start_epoch=$(date +%s)
read beschreibung
dauer=$(( ($(date +%s) - start_epoch) / 60))
echo "$dauer $beschreibung" >>spass.log
)
Für das Protokoll
- Aufgabe 1: Ermittle deine gesamte Spassdauer
- Aufgabe 2: Veraendere den Aufruf, auf dass taeglich eine neue spass-Datei angelegt wird
Einstieg: find & xargs
- find: Dateisystemobjekte nach Kriterien auflisten
- xargs: Standardeingabe in Parameter umwandeln
Mundstopfer
find /home -maxdepth 2 -type f -name .xsession-errors -delete
find /home -maxdepth 2 -type f -name .xsession-errors | xargs rm
Mundstopfer
- Aufgabe 1: Sicheres Löschen der Informationen
- Aufgabe 2: keine Fehlermeldung, falls keine Dateien gefunden wurden
- Aufgabe 3: Sicherer Umgang mit Nutzernamen, die einen Zeilenumbruch enthalten
Einstieg: df & sort & cut & mailx
- df: freier und benutzer Speicher von eingehängten Dateisystemen
- sort: numerisches oder alphabetisches Sortieren von Zeilen
- cut: spaltenweise Filtern
- mailx: nicht-interaktiver Mailversand mit vielen Optionen
Klaustrophobia
df | sed 1d | awk '{ if ($4 < 100000) print $0; }'
Klaustrophobia
- Sortierung nach dem verfügbaren Speicherplatz
- Aufgabe: Formulierung als cron-job-taugliche Zeile mit Mailversand bei Speichermangel
Einstieg: dd & Funktionen
- dd: blockweises Lesen und Schreiben
- Funktionen: Sub-Shell für separate Aufgaben
Heuhaufen
(
read_byte() { local char=$(dd bs=1 count=1); echo -n "$char"; [ -n "$char" ]; }
while read_byte; do dd if=/dev/urandom bs=23 count=1; done
) 2>/dev/null <geheimnis >versteckt
Heuhaufen
- Aufgabe 1: Entschlüssele den Text!
- Aufgabe 2: Vernichte das Geheimnis nach erfolgreicher Versteckung.
Einstieg: sleep & head & tail
- sleep: Wartezeit
- head / tail: führende/abschließende Zeilen ausgeben
Prozesspathologie
(
while sleep 5; do
top -b -n 1 -o "%MEM" | head -12 | tail -5 | sed "s/^/$(date +%Y%m%d%H%M%S) /"
done >>nirwana.log
)
Prozesspathologie
- Aufgabe 1: Anzeige der aktuellen Zeilen auch auf der Konsole (parallel zum Loggen in der Datei).
- Aufgabe 2: Sicherstellen, dass die Datei auch wirklich geschrieben wird, bevor das System neustartet.
- Aufgabe 3: Ermitteln der Prozesszeile zum Zeitpunkt des maximalen Speicherbedarfs eines Prozesses.
Einstieg: ps & who
- ps: Prozesse auflisten
- who: angemeldete Nutzer auflisten
Jagd auf Ikarus
watch "ps -ef | grep sudo | grep -v grep"
Jagd auf Ikarus
- Aufgabe: Wem gehört der Prozess?
Einstieg: basename & wc
- basename: Dateinamen aus einem Pfad extrahieren
- wc: zählen von Zeichen, Worten und Zeilen
Rundungsfehler
find ~ -type f | xargs -n 1 basename | wc | awk '{ print $3 / $1 - 1; }'
Rundungsfehler
- Aufgabe: Stelle sicher, dass dies auch mit Dateinamen funktioniert, die Zeilenumbrüche enthalten.
Übersehene Helfer
- Dateien: cp / mv / rm / rmdir / touch
- Text: cat / cut / join / tr / uniq
- System / Prozesse: chroot / dirname / du / expr / factor / id / nice / printf / pwd / readlink / seq / stat / test / timeout / true / false / uname / uptime