Wissen/Bourne Shell

Aus UUGRN
< Wissen(Weitergeleitet von Bourne Shell)
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Bourne-Shell: Geschichte und Grundlagen

Teil 1: Geschichte

Thompson-Shell

  • Erste Shell für AT&T UNIX (“UNICS”) Version 1 bis 6
  • Name des Programms: “sh” (liegt im Verzeichnis “/bin”). Also lautet der absolute Pfadname /bin/sh,
  • Aufgaben:
    • Starten von Programmen
    • Umleiten von Ausgaben (“Redirection”) in andere Programme (“Filter”) oder in Dateien.
  • Siehe auch Manpage https://www.in-ulm.de/~mascheck/bourne/v3/

Bourne-Shell

  • Nachfolger der Thompson-Shell ab AT&T UNIX Version 7.
  • Hauptaugenmerk auf “Command Language” (mit Bedingunge, Schleifen u.v.a.m.).
    • Syntax der Sprache inspiriert von ALGOL68.
  • Außerdem können Shell-Skripte selbst Filter sein (ging bei Thompson Shell nicht).
  • Seit 1989 quasi quasi unverändert, vergleiche auch: https://en.wikipedia.org/wiki/Bourne_shell#Features_introduced_after_1979
  • Code der Bourne Shell war die Inspiration für den International Obfuscated C Code Contest".

C-Shell

  • Entwickelt von der “Berkeley Group” (BSD) als Alternative zu Bourne Shell.
  • Inspiriert von C-Syntax.
  • Komfortabler als die Bourne Shell für interaktive Benutzung.
  • Gilt inzwischen als veraltet (“C Shell Programming considered harmful”).

Korn-Shell

Bourne-Again-Shell

  • Auftragsarbeit eines Festangestellten der Free Software Foundation für das GNU-Projekt.
    • Auf BSD nicht standardmäßig installiert bzw. oft in /usr/local/bin o.ä.
  • Kompatibel zu Bourne Shell:
    • Spezieller Kompatibilitätsmodus wenn als “sh” aufgerufen
  • Arrays.
  • “shopt” statt “set” für Bash-spezifische Optionen
  • Stark erweiterte Parameter-Expansion
    • z.B. Substitution,
    • Siehe Manpage.
  • Verbesserte Arithmetik.
  • Erweiterte Redirection.
  • Sehr stark verbesserter interaktiver Modus ähnlich Korn Shell.

Almquist-Shell (“ash” bzw. “dash”)

  • Reimplementation der Bourne Shell unter anderer Lizenz.
  • Zuerst für BSD, später portiert auf Debian (dort “dash”).

Z-Shell

  • Reimplementation der Bourne Shell mit stark erweiterten Features.
  • Empfohlen als interaktive, nicht aber als nicht-interaktive Shell.
    • Grund: Shell-Skripte in zsh setzen installierte zsh voraus.

Kompatibilität

  • Kern: Bourne Shell (und deshalb eine Empfehlung).
  • Vorsicht: In "Bourne-kompatiblen" Shells kann man Code schreiben, der in Bourne nicht geht.

Teil 2: Grundlagen

Funktionsweise

  • Betriebsmodus “interaktiv”.
    • Spezialfall “Login-Shell”.
    • Zeilenweise Ein- und Ausgabe über ein tty (“Teletype”, Printer, serielle Schnittstelle, Terminal, Terminal Emulator).
  • Betriebsmodus “non-interaktiv”
  • “Shebang”-Konvention in Skripten (erste Zeile #!/bin/sh ).
  • Kommentare
  • Line Continuation
  • Shell-Optionen, die den Betriebsmodus verändern (z.B. -e, -x)
  • Zeilenbasierter Parser
  • Expansionen
    • Siehe dazu z.B. die Manpage von “dash”, Abschnitt “Word Expansions”
  • Kontrollstrukturen
  • Redirection und Pipes

Grundsätzliche Features

  • “Strings are first-class citizens and the only citizens” – Stephen Bourne
  • Es gibt kein “goto” (Bourne ist ALGOL-Fan)
  • Hauptaufgaben:
    • Zuweisungen
      • Spezialfall: “export”
    • Kommandos ausführen
      • builtins vs. executables
  • Variablen:
    • Einfach: “foo=bar”
    • Export an Subprozesse: “export FOO=bar”
    • Zugriff auf den Wert der Variable:
      • echo "$foo" (“verkürzte Syntax”)
      • echo "${foo}" (“vollständige Syntax”)
    • Variablen mit Bedeutung für die Shell selbst (Beispiele): $PATH, $PS1, $IFS, …
    • “Interessante” Umgebungsvariablen: $PATH, $USER, $SHELL, $PPID, …
  • Expansion:
    • Gute Übersicht:

https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html

    • Besonders wichtig: Parameter-Expansion:
      • Kommandozeilen-Argumente $*, $@ und $0, $1, …
      • Spezial-Features mit “ausführlicher Syntax”:
        • config=${1:-config.inc}:

“Der Wert der Variable”config" ist der Wert des ersten Kommandozeilen-Arguments, es sei denn, dieses wäre leer oder nicht gesetzt, dann soll der Wert ‘config.inc’ lauten."

      • Bourne Shell hat noch andere interessante Parameter-Exansion-Tricks, und Bourne Again Shell noch viel mehr.
    • Wichtig: Command Substitution:
    • Mit Backticks:
  output=`ls | grep foo`
    • oder mit Klammerung:
  output=$(ls | grep foo)
    • Die geklammerte Syntax hat u.a. den Vorteil, dass sie einfacher verschachtelt werden kann.
    • Nützlich: Arithmetik (nur Ganzzahlen): a=0 ; a=$((a+2)) ; echo $a
  • Arbeiten mit Rückgabewerten
    • Abgespeichert in $?
    • Konvention: 0: Erfolg; Sonst: Fehler.
  • Quotierung
    • Klassisch mit ", desweiteren auch mit '
    • Spezialfall: Here-Documents
  sed -e 's/foo/bar/g' << EOF
  Ein foo kam daher
  zum foo und danach noch zu einem anderen foo. 
  EOF
    • Hinweis: Here-Documents kamen im Vortrag aus Zeitgründen nicht dran.
    • Herausforderung: Escaping:
    • Beispiel 1: echo "\"Doppelte\" Anführungszeichen"
    • Beispiel 2: echo '\'Einfache\' Anführungszeichen'
  • Kontrollstrukturen:
    • if true ; then echo "passt." ; else echo "komisch" ; fi
    • bzw. auf mehreren Zeilen:
  if true ; then
     echo "passt"
  else
     echo "komisch"
  fi
  • while true ; do echo "idle ..." ; sleep 1 ; done
  • bzw.
  while true ; do
     echo "idle ..."
  done
  • Generell:
    • Interaktiver Modus: Einzeiler-Syntax.
    • Non-Interaktiver Modus/Skript: Mehrzeilige Syntax.
  • Funktionen definieren
    • Bourne und Bourne Again Shell: xxx() { echo "xxx" ; }
    • Nur Bourne Again Shell: function xxx() { echo "xxx" ; }
    • Empfehlung: Bourne Syntax verwenden, da vorwärtskompatibel.
  • Source Files
    • Hinweis: Kam im Vortrag aus Zeitgründen nicht dran.
    • Inhalt einer anderen Datei an dieser Stelle komplett als Shellcode laden und ausführen.
    • Beispiel: . /usr/local/lib/shell-stuff/config.sh
    • Problem (u.a.): . ./config.sh (Welcher Speicherort von “config.sh” wird hier erwartet?)

Anhang: Das Beispiel "deltmp.sh" aus dem Vortrag

  #!/bin/sh
  # set -e
  dir=${1:-/tmp}
  if find "$dir" -name '*.tmp' > /tmp/find.log 2> /tmp/find.err ; then
     echo "Ausgabe abgeschlossen am $(date)" >> /tmp/find.log
  else
     echo "Fehler beim Durchsuchen am $(date)" >> /tmp/find.log
  fi

Links

Geschichte

Benutzung