Wissen/Bourne Shell: Unterschied zwischen den Versionen

Aus UUGRN
K (→‎Kompatibilität: klarere Formulierung)
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-Skripten selbst Filter sein (ging bei Thompson Shell nicht).
+
* 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 ===
  
* Autragsarbeit eines Festangestellten der Free Software Foundation für das GNU-Projekt.
+
* 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-Skripten in zsh setzen installierte zsh voraus.
+
** Grund: Shell-Skripte in zsh setzen installierte zsh voraus.
  
 
=== Kompatibilität ===
 
=== Kompatibilität ===
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 &quot;$foo&quot;</code> (“verkürzte Syntax”)
 
*** <code>echo &quot;$foo&quot;</code> (“verkürzte Syntax”)
 
*** <code>echo &quot;${foo}&quot;</code> (“vollständige Syntax”)
 
*** <code>echo &quot;${foo}&quot;</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 164: Zeile 164:
 
** 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 Zeitgrpnden nicht dran.
+
** <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>

Version vom 16. Juni 2021, 05:39 Uhr

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 meine 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