On Mon, Aug 26, 2002 at 05:49:20PM +0200, Ernst May-Jung wrote:

> bei mir liegt das in einem ordner der in Path eingetragen ist. 
> und obwohl '#! sh' oder so �hnlich fehlt (ich brauch vielleicht mal ein Kurs 
> dazu :-) l�uft das Ding und syncronisert einfach.

Am Anfang ist unter Unix ein Prozess.  Per Default gibt es zwei, 0
(die idle Task) und 1 (das was dann /sbin/init ist).

Unter Unix gibt es keine Funktion, ein neues Programm in einem neuen
Prozess zu starten.  Also macht man folgendes:

- Aus dem aktuellen Programm/Prozess macht man zwei, n�mlich mittels
  fork() oder vfork().[1][2]

- Der Vater-Prozess erh�lt als R�ckgabewert von fork() die PID des
  Kindes.  Das Kind erh�lt 0 zur�ck.

- Als Konvention wird dann im Kind-Prozess das gew�nschte Programm
  mittels exec() gestartet.  exec() ersetzt den gesamten
  Prozess-Kontext durch ein neues Programm.  Zum �ben in der Shell mal
  "exec top" eingeben.[3]

Andere System haben f�r diesen Ablauf spawn() oder CreateProcess().

Der Charme an fork()/exec() liegt darin, dass man zwischen dem fork()
und dem exec() verschiedene Dinge tun kann - und damit die passende
Umgebung f�r den neuen Prozess aufbauen kann.  Bei Windows muss daf�r
der passende Parameter an CreateProcess() �bergeben werden, und
jedesmal, wenn eine neue Proze�eigenschaft dazu kommt, dann muss das
Interface von CreateProcess() ge�ndert werden.

So, nun kommen wir zu der Shell.  In der Shell geben wir Befehle ein,
und die werden ausgef�hrt.  Und zwar wie folgt:

- Ist es ein Alias?  Aufl�sen und weitermachen.

- Ist es ein interner Befehl?  Dann wird die passende interne Funktion
  ausgerufen.

- Ist es eine Shell-Funktion?  Dann diese ausf�hren.

- Dann ist es wohl ein externe Programm, also suchen wir das im
  Suchpfad und f�hren es per fork() und exec() aus.  Das geht nur,
  wenn das Programm ein bekanntes Format hat.  Dieses erkennt der Kernel
  anhand der ersten zwei Bytes.[5]

- Hat das alles nicht funktioniert, dann k�nnen wir vielleicht das
  Skript in der aktuellen Sitzung/Shell ausf�hren.  Das ist das, was bei
  Dir passiert.  Ungetestet: schreib mal ein "exit" in das Skript.

So, wozu braucht man nun das "#!", wenn denn Dein Skript ja ausgef�hrt
wird?  Man kann als Login-Shell eine andere Shell verwenden, als zum
Ausf�hren von Skripten.  Das ist auf Multi-User-Systemen sogar eher
�blich.  Fr�her hat man auch gerne die csh als Login-Shell verwendet,
aber Skripte in sh/ksh geschrieben.  Und da braucht man dann das
"She-Bang".

Alle Klarheiten beseitigt?

Jochen


[1] Der Unterschied war, dass fr�her bei fork() der gesamte Speicher
kopiert werden musste, bevor es weiter ging.  vfork() hat das nicht
getan, aber andere Einschr�nkungen.  Du denen kommen wir sp�ter.[4]

[2] clone() lassen wir auch erstmal weg.

[3] Bei "no more processes" hat man damit noch einen Schuss frei.

[4] Copy-on-Write, oder auch nicht (wie unter HP-SUX).  Das hat schon
den einen oder anderen verwirrt...

[5] Sind die ersten beiden Bytes "#!", dann ruft der Kernel die
angegebene Shell auf und �bergibt das Skript zur Ausf�hrung an diese.

-- 
#include <~/.signature>: permission denied
----------------------------------------------------------------------------
PUG - Penguin User Group Wiesbaden - http://www.pug.org

Antwort per Email an