hack-hro wiki:
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!


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

System Message: ERROR/3 (<string>, line 244)

Content block expected for the "code" directive; none found.

.. code:: shell-session

ls -l | awk '{ print $9, "t", $3 }'


  • speziell: $0 gibt das gesamte Feld zurück

Arithmetische Ausdrücke

  • +, -, *, /, %

    System Message: WARNING/2 (<string>, line 257); backlink

    Inline emphasis start-string without end-string.

  • 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

    System Message: WARNING/2 (<string>, line 278); backlink

    Inline emphasis start-string without end-string.

  • /= 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!

System Message: ERROR/3 (<string>, line 378)

Document or section may not begin with a transition.

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

hack-hro wiki: Workshops/Shell2 (zuletzt geƤndert am 2015-05-13 22:19:56 durch lars)