GNU Screen erbt meinen PATH am 10.5.8 nicht


11

Ich benutze den Bildschirm täglich für meine Terminalanforderungen und bin ziemlich zufrieden damit. Vor kurzem jedoch habe ich einige Updates an meine Bash - Konfigurationsdateien und ich bemerkte , dass ich verschiedene einstellen PATHElemente ( PATH, MANPATH, INFOPATH, usw.) in 2 Stellen. Ich habe die Dateien so geändert, wie sie sein sollten, und jetzt werden alle meine Umgebungsvariablen einmal festgelegt .bash_profile. Hierin liegt mein Problem.

Anscheinend war der Grund, warum ich sie an zwei Stellen eingestellt habe, der Bildschirm. Bildschirm erscheint nur auszuführen .bashrcund nicht nicht erscheinen meine erben PATHoder jede andere Umgebungsvariablen korrekt von meiner ursprünglichen Bash - Shell. Da es nur ausgeführt wird .bashrcund ich jetzt .bash_profilenur meine Variablen einstelle , erhalte ich eine unvollständige PATH.

Meine Frage ist also, wie ich meine Umgebungsvariablen ohne Duplizierung auf den Bildschirm bringen kann. Das Lesen der BashDokumente scheint darauf hinzudeuten, dass es sich um die Art von Shell handeln könnte, die der Bildschirm zum Anmelden verwendet, dh eine interaktive Shell ohne Anmeldung, aber ich konnte nicht herausfinden, wie der Bildschirm gezwungen werden kann, eine bestimmte Art von Shell zu verwenden, nur die Shell zu verwenden über -s /bin/bash.

Sie können meine Konfigurationsdateien auf meiner GitHub-Seite lesen . Dies ist das Commit-Commit, das den Bildschirm beschädigt hat .

EDIT: Ich benutze Screen version 4.00.03 (FAU) 23-Oct-06und ich neige dazu, es durch aufzurufenscreen -h 50000

BEARBEITEN: Ich konnte dies jetzt auf Cygwin ( CYGWIN_NT-5.1 1.7.1(0.218/5/3) i686, Screen version 4.00.03 (FAU) 23-Oct-06) testen und es zeigt ein anderes Verhalten als auf meinem Mac.

Das spezifische Verhalten, das ich jetzt entdeckt habe, ist, dass in Cygwin die Änderungen, die ich PATHin .bash_profile vornehme, beim Aufrufen des Bildschirms dupliziert werden und die sukzessive Erstellung von Bildschirmfenstern den Pfad nicht dupliziert, sondern .bash_profile neu erstellt.

Um das Verhalten zu veranschaulichen, von dem ich spreche:

Ausgabe von einem neuen Terminal:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Ausgabe vom ersten Aufruf des Bildschirms:

[~]$ screen -h 50000 -s -/bin/bash

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Nachfolgende Anrufe an C-a c:

...

PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack

MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man

Aliases:
alias ..='cd ..'
alias ...='cd ../..'

...

[~]$

Du kannst sehen


Die Duplizierung ist darauf zurückzuführen, dass Sie bash so konfiguriert haben, dass diese Einträge unbedingt hinzugefügt werden. Es handelt sich um eine Anmeldeshell, und Sie weisen den Bildschirm an, bash als Anmeldeshell aufzurufen . Ich habe meine Antwort umgeschrieben, um zu versuchen, die allgemeinen Probleme mit Shells, Bildschirm- und Umgebungsvariablen zu lösen .
Chris Johnsen

Antworten:


16

Bildschirm- und Umgebungsvariablen

Standardmäßig gibt der Bildschirm alle Umgebungsvariablen an seine Shells (und andere Prozesse) weiter, die er zu Beginn der Sitzung hatte (dh durch erneutes Verbinden wird nicht geändert, welche Umgebungsvariablen neuen Shells zugewiesen werden). Da jedoch sowohl die Konfigurationsdateien des Bildschirms als auch der Shells häufig Umgebungsvariablen ändern, gibt es viele Stellen, an denen unerwartete Änderungen vorgenommen werden können. Es gibt einige Variablen, wie z. B. TERM , deren Bildschirm sich fast immer ändert, aber diese sind im Allgemeinen für die Funktionalität erforderlich, die der Bildschirm bietet.

Angenommen , weder die Konfiguration Ihrer Shell noch die Konfiguration des Bildschirms ändern eine Variable mit dem Namen FOOBAR (insgesamt ziemlich wahrscheinlich). Wenn Sie eine Sitzung mit starten FOOBAR=foo screen, haben alle in dieser Sitzung erstellten Shells eine Umgebungsvariable namens FOOBAR mit dem Wert von foo.

Bei Variablen, die entweder vom Bildschirm oder von Ihrer Shell geändert werden, wird es komplizierter .

Fehlende Einstellungen bei Verwendung des Bildschirms

Login Shells

Wenn Sie feststellen, dass einige Einstellungen in vom Bildschirm gestarteten Shells fehlen , liegt dies möglicherweise daran, dass Ihre Shell nur so konfiguriert ist, dass diese Einstellungen für "Login" -Shells aktualisiert werden. Die meisten Muscheln verstehen eine spezielle Konvention (in C: **argv == '-') , der Bildschirm zu verwenden , konfiguriert werden kann.

Per dem Bildschirm Dokumentation :

Shell- Befehl

Legen Sie den Befehl fest, mit dem eine neue Shell erstellt werden soll. Dies überschreibt den Wert der Umgebungsvariablen $ SHELL. Dies ist nützlich, wenn Sie einen tty-Enhancer ausführen möchten, der erwartet, dass das in $ SHELL angegebene Programm ausgeführt wird. Wenn der Befehl mit einem '-' Zeichen beginnt, wird die Shell als Login-Shell gestartet.

Um Bildschirmstart- Shells als "Login" -Shells zu haben, starten Sie den Bildschirm mit screen -s -/bin/bashoder fügen Sie diese Zeile zu Ihrem hinzu .screenrc:

shell -/bin/bash

Passen Sie den Pfad zu der Shell an, die Sie gerade verwenden.

Bildschirm Konfiguration

Fehlende oder Reset - Umgebungsvariablen auch durch sein könnten setenvund unsetenvBefehle in einer Bildschirm - Konfigurationsdatei. Sie müssen sowohl die .screenrc-Datei in Ihrem Home-Verzeichnis als auch die Datei überprüfen, die Ihre Bildschirmkompilierung als 'system screenrc' verwendet (Sie können einen Befehl versuchen strings "$(which screen)" | fgrep -i screenrc, um den Pfadnamen zu finden, der zur Kompilierungszeit konfiguriert wurde - normalerweise / etc / screenrc für einen vom System installierten Bildschirm ; Add-On-Installationen verwenden wahrscheinlich einen anderen Pfadnamen. Sie können SCREENRC=/dev/null SYSSCREENRC=/dev/null screendiese Einstellungsdateien vorübergehend vermeiden, es gibt jedoch eine Option zur Kompilierungszeit, die die effektive Verwendung von SYSSCREENRC verhindert (Vermutlich, damit Systemadministratoren die Erstkonfiguration erzwingen können).

Doppelte Einstellungen bei Verwendung des Bildschirms

Es ist ziemlich üblich, einer Umgebungsvariablen wie PATH in den Konfigurationsdateien einer Shell Elemente hinzuzufügen, damit der aktualisierte Wert für normale Shell-Sitzungen (z. B. xterm oder andere Terminalfenster, Konsolensitzungen usw.) verfügbar ist . Wenn solche Elemente in der Konfiguration pro Shell einer Shell hinzugefügt werden (oder, wenn Sie die -/path/to/shelloben beschriebene Einstellung verwenden, in der Konfiguration für die Anmeldung pro Shell), enthält die vom Bildschirm gestartete Shell wahrscheinlich mehrere Kopien der hinzugefügten Elemente.

Eine Strategie, um dies zu vermeiden, besteht darin, alle Ergänzungen zu Variablen wie PATH in die Konfiguration pro Login Ihrer Shell aufzunehmen und die Verwendung der -/path/to/shellShell-Einstellung mit Bildschirm zu vermeiden .

Eine andere Strategie besteht darin, die neuen Elemente nur bedingt zur Variablen hinzuzufügen. Abhängig von der Shell kann der Code dazu etwas kompliziert sein, er kann jedoch normalerweise zur einfachen Verwendung in eine Shell-Funktion eingekapselt werden.

Eine weitere Strategie besteht darin, immer mit einem festen Wert in Ihren Konfigurationsdateien zu beginnen. Dies kann manchmal zu Problemen beim Verschieben Ihrer Konfigurationsdateien von System zu System führen, wenn die Standardwerte erheblich variieren können.

Diagnose

Wenn Sie nicht direkt erkennen können, wo eine bestimmte Änderung stattfindet, können Sie Folgendes versuchen, um festzustellen, wo die Änderung stattfindet.

Überprüfen Sie den aktuellen Wert in Ihrer ursprünglichen Shell:

echo "$PATH"

Überprüfen Sie, wie die Shell selbst den Wert ändert, wenn eine Unter-Shell erstellt wird:

/bin/bash -c 'echo "$PATH"'

Überprüfen Sie, wie die Shell den Wert ändert, wenn eine 'Login'-Sub-Shell erstellt wird:

perl -e '$s=shift;exec {$s} "-$s", @ARGV or die "unable to start shell"' /bin/bash
echo "$PATH"
exit

Überprüfen Sie, wie der Bildschirm den Wert ändert:

printf '#!/bin/sh\nl=/tmp/echo-var.log;rm -f "$l"; echo $PATH >"$l"' >/tmp/echo-var &&
chmod a+x /tmp/echo-var &&
screen -s /tmp/echo-var &&
cat /tmp/echo-var.log

Dies löst einen Teil meines Problems. Leider geht es nicht den ganzen Weg. Jetzt funktioniert der Bildschirm einwandfrei, screen -s -/bin/bashaber er verhält sich nicht so, wie ich es unter Cygwin auf meinem Arbeitscomputer erwartet habe. Auf diesem Computer screen -h 50000starte ich und erbt einfach meine, PATHohne die Datei erneut zu beziehen. Dies wird jedes Mal ausgeführt, wenn ich ein neues Fenster starte.
Tim Visher

Die Umgebung des Bildschirmprozesses sollte immer von seinen untergeordneten Elementen geerbt werden (mit Ausnahme von Dingen wie TERM, die möglicherweise überschrieben werden). Versuchen Sie FOOBAR=baz screen, echo $FOOBARdie Shell-Fenster von screenund einzuchecken screen -s -/bin/bash. Beide Variationen sollten FOOBAR= haben baz. Wenn Ihr PATHgeändert wird, müssen Sie herausfinden, was es tut. Versuchen Sie SYSSCREENRC=/dev/null SCREENRC=/dev/null screen, wenn das Sie PATHdurchlässt, dann ist es wahrscheinlich ein setenv PATHin /etc/screenrcoder ~/.screenrc. Ansonsten ist es etwas, was du .bashrctust.
Chris Johnsen

Ich habe meine Antwort umfangreich umgeschrieben.
Chris Johnsen

2

Das letzte Mal, als ich ein ähnliches Problem sah, löste ich es, indem ich es screen -lbeim Startbildschirm verwendete.

Sie können die -lOption beim Aufrufen verwenden screen( Anmeldemodus aktivieren ; auch von den Befehlen defloginund logingesteuert .screenrc), um festzulegen, ob der Bildschirm das Fenster standardmäßig anmelden soll (Hinzufügen / Entfernen des Eintrags / etc / utmp).

Der Anmeldemodus ist standardmäßig aktiviert, kann jedoch beim Kompilieren geändert werden. Wenn der Bildschirm nicht mit utmp-Unterstützung kompiliert wurde, sind diese Befehle nicht verfügbar.

Ich brauche den -lModus in Debian Lennys Standardbildschirm (v4.0.3) anscheinend nicht. es scheint standardmäßig aktiviert zu sein. Meine ~/.profileund ~/.bashrcwerden richtig gelesen. Wie rufst du an screen? Welche Version verwenden Sie?


tho unter dieser Theorie screen -lnsollte meine nicht laufen ~/.profile, und es wird immer noch laufen. Probieren Sie die -lFlagge aus, aber dies ist wahrscheinlich nicht die richtige Antwort. werde es für den Moment hier lassen.
Quacksalber 27.

Es scheint, dass -lnur gesteuert wird, ob screender utmpDatei ein Eintrag -lhinzugefügt wird , nicht, ob neue Shells mit eigener Option aufgerufen werden oder der benutzerdefinierte -Befehl exec-with- prefix verwendet wird.
Chris Johnsen


1

Es ist nichts Falsches daran, Ihre .bashrc aus .bash_profile zu beziehen. Wenn Sie Ihren Computer nur lokal verwenden, wird Ihr .bash_profile in den meisten Fällen nur bei Ihrer ersten Anmeldung bezogen (es gibt offensichtlich andere Zeiten, in denen es bezogen wird).

Ich organisiere meine Dateien so, dass ich die Informationen in .bash_profile und für alles andere in .bashrc ablege, wenn ich möchte, dass etwas nur beim Anmelden erledigt wird. PATH ist eine Sache, die ich in mein .bashrc eingefügt habe, und ich beziehe .bashrc in mein .bash_profile.


Würden Sie Ihre .bashrcund .bash_profileDateien gerne irgendwo veröffentlichen, damit ich sie sehen kann? Das Problem, auf das ich stieß, als ich etwas Ähnliches tat, war, dass PATHes jedes Mal größer wurde, wenn ich eine neue Bildschirminstanz erstellte, weil es die alte erbte PATHund dann alles erneut hinzufügte.
Tim Visher

Tut mir leid, Tim, ich habe das nicht gesehen ... Ich habe viele Dinge geändert, damit sie nicht viel Sinn ergeben, aber das ist im Grunde das, was ich tue. # .bash_profile if [-f ~ / .bashrc]; dann . ~ / .bashrc fi Dann habe ich alles andere in .bashrc eingefügt, außer den Dingen, die ich beim ersten Anmelden starten möchte, die auch in .bash_profile gespeichert sind. PATH wird in .bashrc als eine Reihe von Zeilen anstelle einer Pfaddefinition behandelt, wie die meisten exportieren PATH = / path / to / binaries1: $ PATH export PATH = / path / to / binaries2: $ PATH

0

Immer , wenn ich habe ein Problem, dass ich eine Datei erstellen $HOME/.debugund in alle Dateien sourced / ausgeführt während der Anmeldung / Shell aufgerufen werden (zB ~/.bashrc, ~/.bash_profile, ~/.profile, /etc/bashrc, etc.) ich als erste Zeile haben

test -f $HOME/.debug && echo $HOME/.bashrc 1>&2

o.ä. Für ein bestimmtes Debugging können Sie auch Dinge wie hinzufügen

test -f $HOME/.debug && echo PATH now equals $PATH 1>&2

Auf diese Weise können Sie zu 100% sicher sein, welche Dateien verwendet werden oder nicht.

Die Weiterleitung zu stderr ist wichtig, Sie möchten in vielen Situationen nicht, dass etwas stdout durcheinander bringt.


0

Sie können bei .profile bleiben, da das System bashrc nicht berührt (wie bei einer Grafiksitzung). Jetzt haben Sie einfach zwei verschiedene Umgebungsgruppen - eine von .profile und eine für bash von .bashrc.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.