Wissen/Bourne Shell: Unterschied zwischen den Versionen

Aus UUGRN
(Kategorie "FIXME" hinzugefügt)
 
(6 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-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 ===


* Kern: Bourne Shell.
* Kern: Bourne Shell (und deshalb eine Empfehlung).
* Aber Vorsicht: Auch in Bourne-kompatinlen Shells (also allen ausser C-Shell) kann man Code schreiben, der in Bourne ''nicht'' geht.
* 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 &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 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.
*** 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>&quot;</code>, desweiteren auch mit <code>'</code>
** Klassisch mit <code>&quot;</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 &quot;\&quot;Doppelte\&quot; Anführungszeichen&quot;</code>
** Beispiel 1: <code>echo &quot;\&quot;Doppelte\&quot; Anführungszeichen&quot;</code>
** Beispiel 2: <code>echo '\'Einfache\' Anführungszeichen'</code>
** Beispiel 2: <code>echo '\'Einfache\' Anführungszeichen'</code>
* Kontrollstrukturen:
* Kontrollstrukturen:
** <code>if true ; then echo &quot;passt.&quot; ; else echo &quot;komisch&quot; ; fi</code>
** <code>if true ; then echo &quot;passt.&quot; ; else echo &quot;komisch&quot; ; 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 &quot;idle ...&quot; ; sleep 1 ; done</code>
* <code>while true ; do echo &quot;idle ...&quot; ; 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 &quot;xxx&quot; ; }</code>
** Bourne und Bourne Again Shell: <code>xxx() { echo &quot;xxx&quot; ; }</code>
** Nur Bourne Again Shell: <code>function xxx() { echo &quot;xxx&quot; ; }</code>
** Nur Bourne Again Shell: <code>function xxx() { echo &quot;xxx&quot; ; }</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 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>
** Problem (u.a.): <code>. ./config.sh</code> (Welcher Speicherort von “config.sh” wird hier erwartet?)
** Problem (u.a.): <code>. ./config.sh</code> (Welcher Speicherort von “config.sh” wird hier erwartet?)


== Interessante Links ==
== 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 ==


=== Geschichliches ===
=== Geschichte ===


* Die (vereinfachte) Evolution der UNIXe und UNIX-artigen Betriebssysteme: https://upload.wikimedia.org/wikipedia/commons/7/77/Unix_history-simple.svg
* Die (vereinfachte) Evolution der UNIXe und UNIX-artigen Betriebssysteme: https://upload.wikimedia.org/wikipedia/commons/7/77/Unix_history-simple.svg
Zeile 196: Zeile 192:
* Historische Shells praktisch ausprobieren: https://unix50.org/
* Historische Shells praktisch ausprobieren: https://unix50.org/


=== Technische Dokumentation ===
=== Benutzung ===


* 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
* Manual der Bourne Shell, Abschnitt “Expansions”: https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.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 “Pipeline Subprocesses” auf meinem privaten Blog: https://tk-sls.de/wp/5591/7
* 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]

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]

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.ä.
  • 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
  • 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[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]

Benutzung[Bearbeiten]