Gnu Screen: Befehl beim Anhängen ausführen

Gnu Screen: Befehl beim Anhängen ausführen

Gibt es eine Möglichkeit, GNU Screen erkennen zu lassen, wenn es angeschlossen wird, und ein Shell-Skript auszuführen, das ich habe, wenn es angeschlossen wird? Der Grund dafür ist, dass ich meine Anzeigevariablen für die X11-Weiterleitung korrekt halten möchte, aber erkennen muss, wenn Screen erneut an einen anderen Computer angeschlossen wird, um mein Skript auszulösen.

Danke.

Antwort1

Sie können screen -S foo -X setenv DISPLAY "$DISPLAY"; screen -S foo -rddie Umgebung des screenProzesses vor dem Anhängen ändern. Dies hat keine Auswirkungen auf vorhandene Fenster.

Sie können Ihre Shell vielleicht so konfigurieren, dass sie bei jeder Anzeige einer Eingabeaufforderung nach einer Aktualisierung DISPLAY(und jeder anderen relevanten Variable wie ) sucht. (Das bedeutet, dass Sie möglicherweise einmal drücken müssen, wenn die Shell bei der Verbindung der Sitzung an einer Eingabeaufforderung saß.) Bash führt eine Auswertung durch, bevor jede Eingabeaufforderung angezeigt wird. Zsh führt die Funktion aus, bevor jede Eingabeaufforderung angezeigt wird. Wenn Sie beispielsweise die gewünschten Umgebungszuweisungen in ein Skript eingegeben haben (wobei 12345 die PID des Bildschirmprozesses und der Sitzungsname ist), können Sie etwas wie Folgendes verwenden (für Zsh ungetestet; ich glaube nicht, dass Sie ohne Fork in Bash davonkommen werden):XAUTHORITYEnter$PROMPT_COMMANDprecmd~/var/run/screen-12345.foo.env-update.shfoo

precmd () {
  local now=$SECONDS
  set ~/var/run/"screen-$STY.env-update.sh"(Nms-$(($now-$screen_env_time)))
  if [[ $# -ne 0 ]]; then
    screen_env_time=$now
    . ~/var/run/"screen-$STY.env-update.sh"
  fi
}

Unter manchen Betriebssystemen können Sie auch von $PROMPT_COMMANDoder precmdaus die Umgebung des übergeordneten Prozesses lesen (dabei wird vorausgesetzt, dass Sie die Umgebung des Screen-Prozesses aktualisiert haben). Beispielsweise unter Linux mit zsh (nur tun, wenn Sie unter screen arbeiten):

precmd () {
  local record
  while read -r -d $'\0' record /proc/$PPID/environ; do
    case ${record%%=*} in
      DISPLAY|XAUHORITY) export $record;;
    esac
  done
}

Technisch gesehen können Sie die Umgebung eines anderen Prozesses mithilfe eines Debuggers ändern. Es besteht jedoch eine gute Chance, dass dieser Prozess abstürzt, da die internen Datenstrukturen des Programms nicht mit den vom Kernel gespeicherten Daten übereinstimmen.

Beachten Sie, dass keine dieser Lösungen etwas nützt, wenn Sie SSH in einem Bildschirmfenster ausführen.

Antwort2

Was Sie letztendlich wollen, lässt sich nicht umsetzen. Selbst wenn Sie es schaffen, dass screen beim Verbinden ein Skript ausführt, kann es die Umgebung der untergeordneten Prozesse nicht ändern.

Antwort3

Ich denke, Giles' Lösung ist die allgemeinste, hat aber zwei Nachteile: (1) Sie funktioniert erst, nachdem Sie einen Befehl ausgeführt haben, nach dem erneuten Anschließen, und (2) der Befehl wird bei jeder neuen Eingabeaufforderung ausgeführt. (Was soll ich sagen, ich hasse es, CPU-Zyklen zu verschwenden). Es gibt eine Alternative, aber auch die ist nicht perfekt: Beim screenerneuten Anschließen an ein Terminal mit einer anderen Größe als das vorherige Fenster screensendet es das SIGWINCHSignal an die Shell, das Sie abfangen können:

trap some_function SIGWINCH

Ich habe ein Shell-Skript geschrieben (das zusammen mit .bashrc bereitgestellt wird), das diese Tatsache ausnutzt, um das Umschreiben von SSH_AUTH_SOCK und verwandten Variablen beim erneuten Anschließen eines getrennten Terminals zu handhaben. Das Projekt finden Sie hier:https://gitlab.com/otheus.uibk/bashrc-ssh-agent. Das Skript kann leicht geändert werden, um auch in PROMPT_COMMAND integriert zu werden.

Vielleicht können wir ein Update screenmit einer Option durchführen, um SIGWINCH beim erneuten Anfügen zu erzwingen? Ich verwende derzeit 4.1.0 (im Lieferumfang von RedHat 7 enthalten), aber die aktuelle Version ist 4.6.

verwandte Informationen