Guten Morgen,
Entschuldigung dafuer, dass ich jetzt einen neuen Thread anfange. Die Originalmails liegen bei mir zu Hause :-( Also ich habe mir die Quellen von stty angeschaut, zumindest den Teil der mir noch verstaendlich war. stty ermittelt die Groesse des Terminals per getenv aus der Umgebung. Allerdings: COLUMNS und LINES sind ja eigentlich nicht exportiert. Wie schafft es stty, auf die Umgebung des Elternprozesses zuzu- greifen?
Matthias
On Fri, Jan 11, 2002 at 09:24:37AM +0100, Matthias Petermann wrote:
Entschuldigung dafuer, dass ich jetzt einen neuen Thread anfange. Die Originalmails liegen bei mir zu Hause :-( Also ich habe mir die Quellen von stty angeschaut, zumindest den Teil der mir noch verstaendlich war. stty ermittelt die Groesse des Terminals per getenv aus der Umgebung. Allerdings: COLUMNS und LINES sind ja eigentlich nicht exportiert. Wie schafft es stty, auf die Umgebung des Elternprozesses zuzu- greifen?
man fork
Die Kinder erben die Umgebung der Eltern. Sonst w�re es auch sinnfrei irgendwelche Variablen zu setzen, die dann nur die Shell selbst auswerten kann.
Gru�, Eric
On Fri, Jan 11, 2002 at 09:28:59AM +0100, Eric Schaefer wrote:
man fork Die Kinder erben die Umgebung der Eltern. Sonst wäre es auch sinnfrei irgendwelche Variablen zu setzen, die dann nur die Shell selbst auswerten kann.
??
Nach dem Fork haben beide das selbe Datensegment, also auch gleiche Umgebung (bis copy-on-write, dann sinds nicht mehr die selben Datensegment, aber fast die gleichen Inhalte).
Aber ich würde mal unterstellen, daß nach einem anschließenden exec() (für das stty), dann nur noch die exportierten Variablen (eben die Umgebung) da sind.
Man möge mich berichtigen. Ich bin weder Informatiker noch habe ich das alles eben nochmal verifiziert, es ist nur Glauben und Halbwissen ;-)
Best regards from Dresden Viele Gruesse aus Dresden Heiko Schlittermann
On Fri, Jan 11, 2002 at 09:52:54AM +0100, Heiko Schlittermann wrote:
On Fri, Jan 11, 2002 at 09:28:59AM +0100, Eric Schaefer wrote:
man fork Die Kinder erben die Umgebung der Eltern. Sonst w�re es auch sinnfrei irgendwelche Variablen zu setzen, die dann nur die Shell selbst auswerten kann.
??
Nach dem Fork haben beide das selbe Datensegment, also auch gleiche Umgebung (bis copy-on-write, dann sinds nicht mehr die selben Datensegment, aber fast die gleichen Inhalte).
Aber ich w�rde mal unterstellen, da� nach einem anschlie�enden exec() (f�r das stty), dann nur noch die exportierten Variablen (eben die Umgebung) da sind.
Man m�ge mich berichtigen. Ich bin weder Informatiker noch habe ich das alles eben nochmal verifiziert, es ist nur Glauben und Halbwissen ;-)
Ohne das jetzt nachzuschlagen:
In der Shell gebe ich ein: "mutt", die Shell macht ein fork() und im Enkelprozess wird ein exec("mutt") gemacht. Mutt wertet $EDITOR aus. Wenn ich nun selbiges l�sche und (bash) nur per "EDITOR=emacs" die Variable wieder setze ist die doch NICHT exportiert, oder? Aufruf von mutt und schreiben einer Mail ergibt: emacs wird gestartet (ansonsten mit gel�schter EDITOR Variable: "vi". Alles andere w�re ja auch Quark. Das exportieren ist doch IMHO nur daf�r da, da�diese Variablen vom kind an den Parent zur�ckgegeben werden (sonst k�nnte man in Skripen wie .bashrc auch keine Variablen sinnvoll setzen...)
Gru�, Eric
On Fri, Jan 11, 2002 at 07:24:38PM +0100, Eric Schaefer wrote:
Ohne das jetzt nachzuschlagen:
In der Shell gebe ich ein: "mutt", die Shell macht ein fork() und im Enkelprozess wird ein exec("mutt") gemacht. Mutt wertet $EDITOR aus. Wenn ich nun selbiges l�sche und (bash) nur per "EDITOR=emacs" die Variable wieder setze ist die doch NICHT exportiert, oder? Aufruf von mutt und schreiben einer Mail ergibt: emacs wird gestartet (ansonsten mit gel�schter EDITOR Variable: "vi". Alles andere w�re ja auch Quark. Das exportieren ist doch IMHO nur daf�r da, da�diese Variablen vom kind an den Parent zur�ckgegeben werden (sonst k�nnte man in Skripen wie .bashrc auch keine Variablen sinnvoll setzen...)
Zusatz: Die Kinder erben �ber das Datensegment zwar die Umgebung, aber exec l�scht /�berschreibt ja alles. Deshalb wird �ber exec (z.B. execve()) die Umgebung weitergegeben. int execve (const char *filename, char *const argv [],char *const envp[]);
Gru�, Eric
Bonsoir,
On Friday, 11. January 2002 19:24, Eric Schaefer wrote:
Mutt wertet $EDITOR aus. Wenn ich nun selbiges lösche und (bash) nur per "EDITOR=emacs" die Variable wieder setze ist die doch NICHT exportiert, oder? Aufruf von mutt und schreiben einer Mail ergibt: emacs wird gestartet (ansonsten mit gelöschter EDITOR Variable: "vi".
Wie, das Ändern einer Umgebungsvariable nach dem Start eines Programmes außerhalb desselben sorgt dafür, daß ein getenv() im Programm was neues liefert? :)
Alles andere wäre ja auch Quark. Das exportieren ist doch IMHO nur dafür da, daßdiese Variablen vom kind an den Parent zurückgegeben werden (sonst könnte man in Skripen wie .bashrc auch keine Variablen sinnvoll setzen...)
Da gibt es den "Punkt" (.), damit wird das ge-source-t und somit ist dort gar kein Kindprozess am Werk. IMO ist es gar nicht möglich, Umgebungsvariablen im Programm zu setzen und dann vom Elternteil auszulesen. Folgende Problematik hatten wir letztens auf unserem OSS-Entwicklungsserver: - jeder Entwickler bekommt Zugang zum Rechner über ein gemeinsames Login - wenn er sich mit SSH einloggt, wird nochmal Nutzername/Passwort abgefragt, dieses mit einem Eintrag in einer libdb-Datenbank verglichen, und wenn alles stimmt dann landet er in /home/$gemeinsameslogin/home/$seinlogin. Man kann dann nicht einfach $USER setzen in dem Programm was die Datenbank abfragt, sondern muß irgendwelche Tricks verwenden, wobei in einem solchen Fall eine temporäre Datei schon hilft. (Leider gibt es ja keine Strings als Programmrückgabewerte auf herkömmlichen Unixsystemen, sonst könnte man auch ein return $username machen ;)
Oh, und damit's nicht ganz OT ist: static struct winsize window; static int tty_des aus: #include <sys/ioctl.h> -> bits/ioctl-types.h
Josef Spillner
On Fri, Jan 11, 2002 at 07:40:04PM +0100, Josef Spillner wrote:
On Friday, 11. January 2002 19:24, Eric Schaefer wrote:
Mutt wertet $EDITOR aus. Wenn ich nun selbiges l�sche und (bash) nur per "EDITOR=emacs" die Variable wieder setze ist die doch NICHT exportiert, oder? Aufruf von mutt und schreiben einer Mail ergibt: emacs wird gestartet (ansonsten mit gel�schter EDITOR Variable: "vi".
Wie, das �ndern einer Umgebungsvariable nach dem Start eines Programmes au�erhalb desselben sorgt daf�r, da� ein getenv() im Programm was neues liefert? :)
Nein, nat�rlich vor dem Start. Aber eben ohne "export".
Alles andere w�re ja auch Quark. Das exportieren ist doch IMHO nur daf�r da, da�diese Variablen vom kind an den Parent zur�ckgegeben werden (sonst k�nnte man in Skripen wie .bashrc auch keine Variablen sinnvoll setzen...)
Da gibt es den "Punkt" (.), damit wird das ge-source-t und somit ist dort gar kein Kindprozess am Werk. IMO ist es gar nicht m�glich, Umgebungsvariablen im Programm zu setzen und dann vom Elternteil auszulesen.
Ja, hast Recht. Da obiges auch ohne export geht, wozu ist dann export da? Ich dacht immer, ohne export kann ich innerhalb von Skripten keine Variablen setzen die dann au�erhalb sichtbar sind...
Gru�, Eric
On Sat, Jan 12, 2002 at 11:41:36AM +0100, Eric Schaefer wrote:
Nein, natürlich vor dem Start. Aber eben ohne "export". Ja, hast Recht. Da obiges auch ohne export geht, wozu ist dann export da? Ich dacht immer, ohne export kann ich innerhalb von Skripten keine Variablen setzen die dann außerhalb sichtbar sind...
Mit export wird einer Variable das Attribut "exportable" gegeben. (declare -x tut selbiges).
Eine Zuweisung an die Variable selbst verändert dieses Attribut nicht. Erst das *Löschen* mit "unset".
Heiko
On Fri, Jan 11, 2002 at 07:24:38PM +0100, Eric Schaefer wrote:
Nach dem Fork haben beide das selbe Datensegment, also auch gleiche Umgebung (bis copy-on-write, dann sinds nicht mehr die selben Datensegment, aber fast die gleichen Inhalte).
Aber ich würde mal unterstellen, daß nach einem anschließenden exec() (für das stty), dann nur noch die exportierten Variablen (eben die Umgebung) da sind.
Man möge mich berichtigen. Ich bin weder Informatiker noch habe ich das alles eben nochmal verifiziert, es ist nur Glauben und Halbwissen ;-)
In der Shell gebe ich ein: "mutt", die Shell macht ein fork() und im Enkelprozess wird ein exec("mutt") gemacht.
Mutt wertet $EDITOR aus. Wenn ich nun selbiges lösche und (bash) nur per "EDITOR=emacs" die Variable wieder setze ist die doch NICHT exportiert, oder? Aufruf von mutt und schreiben einer Mail ergibt: emacs wird
export EDITOR=emacs EDITOR= export
.. Du wirst sehen, die Variable ist immer noch exportiert. Wie also "löschst" Du die Variable? "unset" löscht wirklich die Variable.
gestartet (ansonsten mit gelöschter EDITOR Variable: "vi". Alles andere wäre ja auch Quark. Das exportieren ist doch IMHO nur dafür da, daßdiese Variablen vom kind an den Parent zurückgegeben werden
Nein, vom Kind wird generell außer dem exit-Wert nichts an den Parent zurückgegeben. (Prozess-Sicherheit)
(sonst könnte man in Skripen wie .bashrc auch keine Variablen sinnvoll setzen...)
.bashrc wird in der laufenden Umgebung ausgeführt:
source .bashrc oder . .bashrc
Heiko
On Fri, Jan 11, 2002 at 09:24:37AM +0100, Matthias Petermann wrote:
den Teil der mir noch verstaendlich war. stty ermittelt die Groesse des Terminals per getenv aus der Umgebung. Allerdings: COLUMNS und LINES sind ja eigentlich nicht exportiert. Wie schafft es stty, auf die Umgebung des Elternprozesses zuzu- greifen?
Sicher? Bei mir sind beide Variablen nicht gesetzt und trotzdem weiß stty, wie groß das Fenster ist.
Heiko
On Fri, Jan 11, 2002 at 09:42:35AM +0100, heiko wrote:
On Fri, Jan 11, 2002 at 09:24:37AM +0100, Matthias Petermann wrote:
den Teil der mir noch verstaendlich war. stty ermittelt die Groesse des Terminals per getenv aus der Umgebung. Allerdings: COLUMNS und LINES sind ja eigentlich nicht exportiert. Wie schafft es stty, auf die Umgebung des Elternprozesses zuzu- greifen?
Sicher? Bei mir sind beide Variablen nicht gesetzt und trotzdem weiß stty, wie groß das Fenster ist.
Bei mir sieht das etwa so aus: (in stty.c) Ich denke mal, daß Linux TIOCGWINSZ definiert hat, denn nur, wenn's nicht ist, wird getenv() genutzt. In stty.c:screen_columns() findest Du, wenn Du genau hinsiehst, etwa folgendes:
int screen_columns(void) { #ifdef TIOCGWINSZ ... ... if (get_win_size(...)) return win.wins_col; #endif ... ... ... = getenv("COLUMNS"); }
Also wird der erste Teil probiert, wenn TIOCGWINSZ definiert ist, und wenn's dann trotzdem schief ging, wird nach der Umgebungs-Variable COLUMNS geschaut.
...
Und hier die Funktion, die Du wahrscheinlich gesucht hast (auch aus stty.c):
static int get_win_size (int fd, struct winsize *win) { int err = ioctl (fd, TIOCGWINSZ, (char *) win); return err; }
...
Best regards from Dresden Viele Gruesse aus Dresden Heiko Schlittermann
Hallo,
ich kann leider erst jetzt an meinen PC und bedanke mich erst einmal für die vielen Antworten. Das mit den export- ierten Shell-Variablen sowie fork() und exec() hatten wir glücklicherweise vor etwa einer Woche in der Vorlesung :-)
Der Hinweis auf ioctl war sehr gut, ich hab das Auslesen der Terminal-Größe jetzt folgendermaßen realisiert:
{ int fd,err; struct winsize win;
fd = open("/dev/tty", O_RDONLY | O_NONBLOCK); err = ioctl(fd, TIOCGWINSZ, &win); printf("Exit:%d,rows:%d,cols:%d\n",err,win.ws_row,win.ws_col); close(fd); }
Allerdings hab ich nirgends gelesen, ob ich das tty einfach so öffnen darf, wie ich das hier getan habe. Skeptisch bin ich vor allem geworden, da bei mir der 'fd' nach open den Wert 3 hat. Wenn ich allerdings für 'fd' in der ioctl- Anweisung einfach 0 eintrage, funktioniert das Programm trotzdem. Irgendwo im Netz habe ich ein ähnliches Beispiel gefunden, wo nur eine feste 0 in ioctl stand. Ist 0 ein standardmäßig geöffneter Dateidescriptor auf das Terminal?
Viele Grüße,
Matthias
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Sunday 13 January 2002 21:16, Matthias Petermann wrote:
Allerdings hab ich nirgends gelesen, ob ich das tty einfach so öffnen darf, wie ich das hier getan habe. Skeptisch bin ich vor allem geworden, da bei mir der 'fd' nach open den Wert 3 hat. Wenn ich allerdings für 'fd' in der ioctl- Anweisung einfach 0 eintrage, funktioniert das Programm trotzdem. Irgendwo im Netz habe ich ein ähnliches Beispiel gefunden, wo nur eine feste 0 in ioctl stand. Ist 0 ein standardmäßig geöffneter Dateidescriptor auf das Terminal?
standardmaessig sind drei Deskriptoren schon offen (von der Shell geerbt):
standard in = 0 (STDIN_FILENO) standard out = 1 (STDOUT_FILENO) standard error = 2 (STDERR_FILENO)
lt. Standard soll man die Konstanten in Klammern benutzen, die in <unistd.h> definiert sind.
Stan^wKonrad
- -- BOFH excuse #273:
The cord jumped over and hit the power switch.
Konrad, vielen Dank für die Auskunft. Jetzt ist mir einiges klar geworden :-)
Matthias
Hallo Matthias,
On Sun, Jan 13, 2002 at 09:16:09PM +0100, Matthias Petermann wrote:
fd = open("/dev/tty", O_RDONLY | O_NONBLOCK); err = ioctl(fd, TIOCGWINSZ, &win);
Allerdings hab ich nirgends gelesen, ob ich das tty einfach so öffnen darf, wie ich das hier getan habe. Skeptisch bin ich vor allem geworden, da bei mir der 'fd' nach open den Wert 3 hat. Wenn ich allerdings für 'fd' in der ioctl- Anweisung einfach 0 eintrage, funktioniert das Programm trotzdem. Irgendwo im Netz habe ich ein ähnliches Beispiel gefunden, wo nur eine feste 0 in ioctl stand. Ist 0 ein standardmäßig geöffneter Dateidescriptor auf das Terminal?
Wie Konrad schon schrieb, ist die 0 die Standardeingabe des Prozesses. Diese ist nicht notwendigerweise identisch mit dem Terminal (Stichwort: E/A-Umleitung). /dev/tty ist das dem Prozess zugeordnete Terminal. Ich wuerde empfehlen, den Rueckgabewert von open auf Fehler zu testen, falls das Programm mal ohne Terminal laufen sollte (z.B. von cron o.ae. aus).
Holger
On Sun, Jan 13, 2002 at 09:16:09PM +0100, Matthias Petermann wrote:
fd = open("/dev/tty", O_RDONLY | O_NONBLOCK);
Allerdings hab ich nirgends gelesen, ob ich das tty einfach so öffnen darf, wie ich das hier getan habe. Skeptisch bin ich vor allem geworden, da bei mir der 'fd' nach open
Dürfte funktionieren. Ich weiß nicht, was passiert, wenn der Prozess kein tty bekommt.
den Wert 3 hat. Wenn ich allerdings für 'fd' in der ioctl- Anweisung einfach 0 eintrage, funktioniert das Programm
3 ist der nächste freie Deskriptor. 0, 1, 2 sind für STD{IN,OUT,ERR} schon verwendet. STDIN ist wahrscheinlich bei Dir im Augenblick auch das Terminal, deswegen funktioniert das, aber was passiert, wenn Du
cat FILE | programm
machst und in "programm" dann die Fenstergröße von 0 ermittelst - das wird schwer.
Heik
lug-dd@mailman.schlittermann.de