Wissen/Bourne Shell: Unterschied zwischen den Versionen
Aus UUGRN
< Wissen
Tilt (Diskussion | Beiträge) (Beispiel deltmp.sh aus dem Vortrag hinzugefügt) |
K (→Kompatibilität) |
||
(5 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 21: | Zeile 21: | ||
* Hauptaugenmerk auf “Command Language” (mit Bedingunge, Schleifen u.v.a.m.). | * Hauptaugenmerk auf “Command Language” (mit Bedingunge, Schleifen u.v.a.m.). | ||
** Syntax der Sprache inspiriert von ALGOL68. | ** Syntax der Sprache inspiriert von ALGOL68. | ||
* Außerdem können Shell- | * 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 | * 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". | * Code der Bourne Shell war die Inspiration für den International Obfuscated C Code Contest". | ||
Zeile 37: | Zeile 37: | ||
* Mehr Funktionen. | * Mehr Funktionen. | ||
* Sehr viel besser für interaktive Benutzung: | * Sehr viel besser für interaktive Benutzung: | ||
** History | ** History | ||
** Commandline editing, | ** Commandline editing, | ||
** Job-Kontrolle. | ** Job-Kontrolle. | ||
Zeile 47: | Zeile 47: | ||
=== Bourne-Again-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 <code>/usr/local/bin</code> o.ä. | ** Auf BSD nicht standardmäßig installiert bzw. oft in <code>/usr/local/bin</code> o.ä. | ||
* Kompatibel zu Bourne Shell: | * Kompatibel zu Bourne Shell: | ||
Zeile 69: | Zeile 69: | ||
* Reimplementation der Bourne Shell mit stark erweiterten Features. | * Reimplementation der Bourne Shell mit stark erweiterten Features. | ||
* Empfohlen als interaktive, nicht aber als nicht-interaktive Shell. | * Empfohlen als interaktive, nicht aber als nicht-interaktive Shell. | ||
** Grund: Shell- | ** Grund: Shell-Skripte in zsh setzen installierte zsh voraus. | ||
=== Kompatibilität === | === Kompatibilität === | ||
* Kern: Bourne Shell. | * Kern: Bourne Shell (und deshalb eine Empfehlung). | ||
* | * Vorsicht: In "Bourne-kompatiblen" Shells kann man Code schreiben, der in Bourne ''nicht'' geht. | ||
== Teil 2: Grundlagen == | == Teil 2: Grundlagen == | ||
Zeile 84: | Zeile 84: | ||
** Zeilenweise Ein- und Ausgabe über ein tty (“Teletype”, Printer, serielle Schnittstelle, Terminal, Terminal Emulator). | ** Zeilenweise Ein- und Ausgabe über ein tty (“Teletype”, Printer, serielle Schnittstelle, Terminal, Terminal Emulator). | ||
* Betriebsmodus “non-interaktiv” | * Betriebsmodus “non-interaktiv” | ||
* “Shebang”-Konvention in Skripten (erste Zeile <code>#!/bin/sh</code>). | * “Shebang”-Konvention in Skripten (erste Zeile <code>#!/bin/sh</code> ). | ||
* Kommentare | * Kommentare | ||
* Line Continuation | * Line Continuation | ||
Zeile 109: | Zeile 109: | ||
*** <code>echo "$foo"</code> (“verkürzte Syntax”) | *** <code>echo "$foo"</code> (“verkürzte Syntax”) | ||
*** <code>echo "${foo}"</code> (“vollständige Syntax”) | *** <code>echo "${foo}"</code> (“vollständige Syntax”) | ||
** Variablen mit Bedeutung für die Shell selbst (Beispiele): PATH, PS1, IFS, … | ** Variablen mit Bedeutung für die Shell selbst (Beispiele): $PATH, $PS1, $IFS, … | ||
** “Interessante” Umgebungsvariablen: PATH, USER, SHELL, PPID, … | ** “Interessante” Umgebungsvariablen: $PATH, $USER, $SHELL, $PPID, … | ||
* Expansion: | * Expansion: | ||
** Gute Übersicht: | ** Gute Übersicht: | ||
Zeile 124: | Zeile 124: | ||
** Wichtig: Command Substitution: | ** Wichtig: Command Substitution: | ||
** Mit Backticks: | ** Mit Backticks: | ||
output=`ls | grep foo` | output=`ls | grep foo` | ||
** <em>oder</em> mit Klammerung: | ** <em>oder</em> mit Klammerung: | ||
output=$(ls | grep foo) | output=$(ls | grep foo) | ||
** Die geklammerte Syntax hat u.a. den Vorteil, dass sie einfacher verschachtelt werden kann. | |||
** Nützlich: Arithmetik (nur Ganzzahlen): <code>a=0 ; a=$((a+2)) ; echo $a</code> | ** Nützlich: Arithmetik (nur Ganzzahlen): <code>a=0 ; a=$((a+2)) ; echo $a</code> | ||
* Arbeiten mit Rückgabewerten | * Arbeiten mit Rückgabewerten | ||
** Abgespeichert in <code>$?</code> | ** Abgespeichert in <code>$?</code> | ||
** Konvention: 0: Erfolg; Sonst: Fehler. | ** Konvention: 0: Erfolg; Sonst: Fehler. | ||
* Quotierung | * Quotierung | ||
** Klassisch mit <code>"</code>, desweiteren auch mit <code>'</code> | ** Klassisch mit <code>"</code>, desweiteren auch mit <code>'</code> | ||
** Spezialfall: Here-Documents | ** Spezialfall: Here-Documents | ||
sed -e 's/foo/bar/g' << EOF | sed -e 's/foo/bar/g' << EOF | ||
Ein foo kam daher | Ein foo kam daher | ||
zum foo und danach noch zu einem anderen foo. | zum foo und danach noch zu einem anderen foo. | ||
EOF | EOF | ||
** <em>Hinweis:</em> Here-Documents kamen im Vortrag aus Zeitgründen nicht dran. | ** <em>Hinweis:</em> Here-Documents kamen im Vortrag aus Zeitgründen nicht dran. | ||
** Herausforderung: Escaping: | ** Herausforderung: Escaping: | ||
** Beispiel 1: <code>echo "\"Doppelte\" Anführungszeichen"</code> | ** Beispiel 1: <code>echo "\"Doppelte\" Anführungszeichen"</code> | ||
** Beispiel 2: <code>echo '\'Einfache\' Anführungszeichen'</code> | ** Beispiel 2: <code>echo '\'Einfache\' Anführungszeichen'</code> | ||
* Kontrollstrukturen: | * Kontrollstrukturen: | ||
** <code>if true ; then echo "passt." ; else echo "komisch" ; fi</code> | ** <code>if true ; then echo "passt." ; else echo "komisch" ; fi</code> | ||
** bzw. auf mehreren Zeilen: | ** bzw. auf mehreren Zeilen: | ||
if true ; then | if true ; then | ||
echo "passt" | echo "passt" | ||
Zeile 161: | Zeile 151: | ||
echo "komisch" | echo "komisch" | ||
fi | fi | ||
* <code>while true ; do echo "idle ..." ; sleep 1 ; done</code> | * <code>while true ; do echo "idle ..." ; sleep 1 ; done</code> | ||
* bzw. | * bzw. | ||
while true ; do | while true ; do | ||
echo "idle ..." | echo "idle ..." | ||
done | done | ||
* Generell: | * Generell: | ||
** Interaktiver Modus: Einzeiler-Syntax. | ** Interaktiver Modus: Einzeiler-Syntax. | ||
** Non-Interaktiver Modus/Skript: Mehrzeilige Syntax. | ** Non-Interaktiver Modus/Skript: Mehrzeilige Syntax. | ||
* Funktionen definieren | * Funktionen definieren | ||
** Bourne und Bourne Again Shell: <code>xxx() { echo "xxx" ; }</code> | ** Bourne und Bourne Again Shell: <code>xxx() { echo "xxx" ; }</code> | ||
** Nur Bourne Again Shell: <code>function xxx() { echo "xxx" ; }</code> | ** Nur Bourne Again Shell: <code>function xxx() { echo "xxx" ; }</code> | ||
** Empfehlung: Bourne Syntax verwenden, da vorwärtskompatibel. | ** Empfehlung: Bourne Syntax verwenden, da vorwärtskompatibel. | ||
* Source Files | * Source Files | ||
** <em>Hinweis:</em> Kam im Vortrag aus | ** <em>Hinweis:</em> Kam im Vortrag aus Zeitgründen nicht dran. | ||
** Inhalt einer anderen Datei an dieser Stelle komplett als Shellcode laden und ausführen. | ** Inhalt einer anderen Datei an dieser Stelle komplett als Shellcode laden und ausführen. | ||
** Beispiel: <code>. /usr/local/lib/shell-stuff/config.sh</code> | ** Beispiel: <code>. /usr/local/lib/shell-stuff/config.sh</code> | ||
Zeile 210: | Zeile 195: | ||
* POSIX, Abschnitt “Shell Command Language” (aka “POSIX-Shell”): https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html | * 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 | * Manpage der “Debian Almquist Shell”: https://linux.die.net/man/1/dash | ||
* Abschnitt | * Manual der Bourne Again Shell, Abschnitt “Expansions”: https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html | ||
[[Kategorie:FIXME]] | [[Kategorie:FIXME]] |
Aktuelle Version vom 8. April 2024, 15:35 Uhr
Bourne-Shell: Geschichte und Grundlagen[Bearbeiten]
- Datum: 5. Februar 2021
- Referent: Tilman Kranz tilt@linuxfoo.de
- Ca. 120 Minuten
Teil 1: Geschichte[Bearbeiten]
Thompson-Shell[Bearbeiten]
- 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[Bearbeiten]
- 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[Bearbeiten]
- 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[Bearbeiten]
- 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[Bearbeiten]
- 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”)[Bearbeiten]
- Reimplementation der Bourne Shell unter anderer Lizenz.
- Zuerst für BSD, später portiert auf Debian (dort “dash”).
Z-Shell[Bearbeiten]
- 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[Bearbeiten]
- Kern: Bourne Shell (und deshalb eine Empfehlung).
- Vorsicht: In "Bourne-kompatiblen" Shells kann man Code schreiben, der in Bourne nicht geht.
Teil 2: Grundlagen[Bearbeiten]
Funktionsweise[Bearbeiten]
- 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[Bearbeiten]
- “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[Bearbeiten]
#!/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[Bearbeiten]
Geschichte[Bearbeiten]
- 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[Bearbeiten]
- 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