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
- Datum: 5. Februar 2021
- Referent: Tilman Kranz tilt@linuxfoo.de
- Ca. 120 Minuten
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
- Kompatibel zur Bourne-Shell.
- Mehr Funktionen.
- Sehr viel besser für interaktive Benutzung:
- History
- Commandline editing,
- Job-Kontrolle.
- Wichtige Versionen:
- 88: Grundlage für POSIX:
- 93: Kompletter Rewrite, viel mächtiger, verbraucht aber viel mehr Speicher und CPU.
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.ä.
- Auf BSD nicht standardmäßig installiert bzw. oft in
- 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
- Zuweisungen
- 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}
:
- Kommandozeilen-Argumente
- Besonders wichtig: Parameter-Expansion:
“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.
- Abgespeichert in
- Quotierung
- Klassisch mit
"
, desweiteren auch mit'
- Spezialfall: Here-Documents
- Klassisch mit
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.
- Bourne und Bourne Again Shell:
- 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
- Die (vereinfachte) Evolution der UNIXe und UNIX-artigen Betriebssysteme: https://upload.wikimedia.org/wikipedia/commons/7/77/Unix_history-simple.svg
- Grundsätzliche Funktionsweise (Diagramm): https://developer.ibm.com/developer/default/tutorials/l-linux-shells/images/figure2.gif
- Ken Thompson, Entwickler der ersten UNIX-Shell: https://de.wikipedia.org/wiki/Ken_Thompson
- Handbuch für “sh” (Thompson-Shell) in UNIX Version 3 (1973): https://www.in-ulm.de/~mascheck/bourne/v3/
- Vortrag von Stephen Bourne, Entwickler der Bourne-Shell: https://www.youtube.com/watch?v=2kEJoWfobpA
- “Csh Programming Considered Harmful”: https://www-uxsup.csx.cam.ac.uk/misc/csh.html
- Historische Shells praktisch ausprobieren: https://unix50.org/
Benutzung
- POSIX, Abschnitt “Shell Command Language” (aka “POSIX-Shell”): https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
- Manpage der “Debian Almquist Shell”: https://linux.die.net/man/1/dash
- Manual der Bourne Again Shell, Abschnitt “Expansions”: https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html