Umgebungsvariablen für Bildschirmsitzungen aktualisieren, um die neuen grafischen Anmeldungen wiederzugeben?

10687
Ryan Thompson

Ich benutze Linux, und ich erledige alle meine Befehlszeilenarbeiten in einer einzigen Bildschirmsitzung, sodass ich meine grafischen Anmeldedaten und dergleichen neu starten kann, ohne meine Terminals zu verlieren. Wenn ich mich jedoch abmelden und wieder bei meiner grafischen Sitzung anmelden, werden dadurch alle meine Umgebungsvariablen für die Sitzung geändert, z. B. DBus-Sitzungen. Dies bedeutet, dass meine Bildschirmsitzung nach dem erneuten Anmelden jetzt die alten (und falschen) Umgebungsvariablen hat. Wenn ich jetzt versuche, grafische Programme von meiner Bildschirmsitzung aus zu starten, wird im besten Fall eine Warnung ausgegeben, dass keine Verbindung zum Sitzungsbus hergestellt werden kann. Im schlimmsten Fall beginnen sie nicht vollständig.

Was ich also suche, ist eine Möglichkeit, Umgebungsvariablen in einer laufenden Bildschirminstanz zu ändern, so dass alle nachfolgend erstellten Bildschirmfenster die neuen Umgebungsvariablen übernehmen. Gibt es eine Möglichkeit, dies zu tun?

18
Aha! Ich habe gerade die gesamte Bildschirm-Manpage durchgeblättert, um Folgendes zu finden: `setenv [var [string]] Setzt die Umgebungsvariable var auf value string. Wenn nur var angegeben wird, wird der Benutzer aufgefordert, einen Wert einzugeben. Wenn keine Parameter angegeben werden, werden Sie zur Eingabe von Variablen und Werten aufgefordert. Die Umgebung wird von allen anschließend gegabelten Schalen geerbt. " Ryan Thompson vor 14 Jahren 2
Sie können setenv aufrufen, indem Sie -X zum Bildschirm wechseln. Leider funktioniert es nur für alle anschließend gegabelten Schalen, nicht für die aktuelle Schale. Boris Bukh vor 12 Jahren 0
Beachten Sie, dass [byobu] (http://byobu.co/) jetzt eine Lösung für Bildschirm und Tmux enthält. Ryan Thompson vor 9 Jahren 0

3 Antworten auf die Frage

8
Benjamin Bannier

Sie können ein Shell-Skript nicht von der screenSitzung aus starten, da es die alte Umgebung erben würde. Sie können jedoch ein FIFO verwenden, um die neuen Umgebungsvariablen in die alte Bildschirmsitzung zu übernehmen. Sie können dieses FIFO füllen, wenn Sie Ihre grafische Sitzung starten.

#!/bin/bash FIFO=/tmp/your_variables [ -e $FIFO ] && cat $FIFO > /dev/null || mkfifo $FIFO  # save number of variables that follow NVARS=2 echo $NVARS > $FIFO echo ENV1=sth1 > $FIFO echo ENV2=sth2 > $FIFO 

Starten Sie das Skript beim Anmelden im Hintergrund (es wird nur beendet, wenn alle Variablen daraus gelesen werden).

Nun können Sie aus dem FIFO lesen, zB diese Funktion zu Ihrem hinzufügen .bashrc

update_session() { FIFO=/tmp/your_variables  NVAR=$(cat $FIFO) for i in $(seq $NVAR); do export $(cat $FIFO) done #delete the pipe, or it will not work next time  rm $FIFO } 

so können Sie in Ihrer alten screenSitzung

update_session 
Müssten Sie dies nicht einmal pro Fenster in der laufenden Sitzung tun, um die Haupt-Shell des Fensters zu ändern? quack quixote vor 14 Jahren 0
Schön, auch wenn ~ quack sagt, Sie müssen jede Shell unabhängig voneinander aktualisieren. dmckee vor 14 Jahren 0
Richtig, Sie müssen das in jeder Shell in `screen` tun. AFAIK `screen` stellt keine Steckdosen oder ähnliches zur Verfügung, um mit laufenden Sitzungen von außen zu kommunizieren. Benjamin Bannier vor 14 Jahren 0
@dmckee aber natürlich hat jede * neue * `screen`-Sitzung bereits die letzten Umgebungsvariablen Benjamin Bannier vor 14 Jahren 0
Ich habe mich entschieden, diese Antwort jetzt zu akzeptieren. Wenn ich jemals dazu komme, dies zu implementieren, werde ich es aktualisieren. Aber jetzt reicht es aus, ein warmes, unscharfes Gefühl zu haben, zu wissen, dass es theoretisch möglich ist. Ryan Thompson vor 14 Jahren 0
2
Ryan Thompson

Ich habe dazu ein Skript implementiert. Sie können es hier erhalten: https://github.com/DarwinAwardWinner/screen-sendenv

Nachdem er screen-sendenv.pyin denen $PATH, können Sie den folgenden Code - Schnipsel in Ihren .bashrc verwenden:

VARS_TO_UPDATE="DISPLAY DBUS_SESSION_BUS_ADDRESS SESSION_MANAGER GPG_AGENT_INFO" screen_pushenv () { screen-sendenv.py -t screen $VARS_TO_UPDATE } tmux_pushenv () { screen-sendenv.py -t tmux $VARS_TO_UPDATE } screen_pullenv () { tempfile=$(mktemp -q) && { for var in $VARS_TO_UPDATE; do screen sh -c "echo export $var=\$$var >> \"$tempfile\"" done . "$tempfile" rm -f "$tempfile" } } tmux_pullenv () { for var in $VARS_TO_UPDATE; do expr="$(tmux showenv | grep "^$var=")" if [ -n "$expr" ]; then export "$expr" fi done } 

Um es zu verwenden, führen screen_pushenvSie es einfach vor dem Ausführen aus, screen -rum es erneut zu Ihrer Bildschirmsitzung hinzuzufügen. Nach dem Anhängen mit screen -rkönnen Sie die Umgebung in Ihren vorhandenen Shells mit aktualisieren screen_pullenv. Die tmux-Funktionen erreichen dasselbe für tmux, einen anderen Terminal-Multiplexer, der dem Bildschirm ähnlich ist.

Wow Ryan, das ist viel Code. Was stimmte nicht mit der zuvor akzeptierten Antwort (es war zumindest inspirierend)? Benjamin Bannier vor 12 Jahren 0
Nun, ich habe entdeckt, dass screen (und auch tmux) einen "setenv" -Befehl haben, der eine Umgebungsvariable für screen selbst festlegt, nicht die Shell im aktuellen Bildschirmfenster. Das bedeutet, dass nach der Verwendung meines Skripts alle neu erstellten Fenster in dieser Bildschirmsitzung automatisch die neue Umgebung erhalten, ohne dass das Aktualisierungsskript in jedem von ihnen ausgeführt werden muss. Natürlich kann ein Aktualisierungsskript dennoch nützlich sein, um vorhandene Shells zu aktualisieren, aber Sie müssen es erneut schreiben, um nicht aus einem FIFO zu lesen, sondern die screen / tmux-Sitzung selbst nach den neuen Werten abzufragen. Ryan Thompson vor 12 Jahren 1
Sie können sehen, wie Sie Variablen aus der Screen / tmux-Sitzung in die aktuelle Shell laden [hier] (http://bazaar.launchpad.net/~kirkland/byobu/trunk/view/head:/usr/bin/byobu-reconnect) -sockets) in den Funktionen `screen_update` und` tmux_update`. Ich werde meine Antwort mit einer byobu-unabhängigen Version davon aktualisieren. Ryan Thompson vor 12 Jahren 0
Um Ihre Frage direkt zu beantworten, was falsch war, beantwortet Ihre Antwort die Frage nicht ganz, sondern beantwortet eher eine verwandte Frage. Sie zeigen, wie Sie Umgebungsvariablen in einer Shell aktualisieren, die in einer Bildschirmsitzung ausgeführt wird, nicht jedoch, wie Sie Umgebungsvariablen in der Bildschirmsitzung selbst aktualisieren (dh neu erzeugte Fenster übernehmen die neuen Werte). Ich akzeptierte es damals, weil es immer noch eine gute Lösung war, aber ich hatte immer vorgehabt, * tatsächlich * eine echte Antwort auf meine Frage zu implementieren. Also nichts persönliches. Ryan Thompson vor 12 Jahren 1
Hey Ryan, danke für die Antwort. Nun, da Sie "setenv" erwähnt haben, sehe ich, wie das besser ist. Es war nicht offensichtlich aus dem Code, mit dem Sie verlinkt haben. Danke noch einmal! Benjamin Bannier vor 12 Jahren 0
Ich musste `sync` vor` hinzufügen. "$ tempfile" `, um mit Home-Verzeichnissen auf NFS zu arbeiten. drizzd vor 6 Jahren 0
0
wecac

Dies ist wahrscheinlich eine einfachere Lösung (Sie entscheiden). Der wichtige Teil ist der Alias, der die savedisplayFunktion jedes Mal aufruft, wenn der screenBefehl ausgeführt wird. Die Befehle werden nicht automatisch ausgeführt und können daher ~/.bashrcanstelle von etwas sehr Spezialisiertem eingefügt werden ~/.ssh/rc.

savedisplay() { # Write latest bash display to a file, This is used to  # update running bash sessions for a "screen -r" echo "export DISPLAY=$DISPLAY" > ~/.XDISPLAY echo "export XAUTHORITY=$XAUTHORITY" >> ~/.XDISPLAY # This will only update the environment for new windows screen -X setenv DISPLAY $DISPLAY screen -X setenv XAUTHORITY $XAUTHORITY }  # run this to update env variable in a running session updatedisplay() { source ~/.XDISPLAY  }  alias screen='savedisplay && screen'