18

Я использую linux, и мне нравится выполнять всю работу с командной строкой в рамках одного сеанса экрана, чтобы я мог перезапустить свой графический вход в систему и тому подобное, не теряя свои терминалы. Однако, когда я выхожу из системы и возвращаюсь в свой графический сеанс, это меняет все переменные среды моего сеанса, такие как сеансы DBus. Это означает, что после повторного входа в систему мой экранный сеанс теперь имеет старые (и неправильные) переменные среды. Так что теперь, когда я пытаюсь запустить графические программы из моего сеанса экрана, в лучшем случае они выдают предупреждение о невозможности подключения к сеансовой шине. В худшем случае они не запускаются полностью.

Итак, я ищу способ изменения переменных окружения в работающем экземпляре экрана, чтобы все создаваемые впоследствии окна экрана наследовали новые переменные среды. Есть ли способ сделать это?

3 ответа3

8

Вы не можете запустить скрипт оболочки из сеанса screen так как он унаследует старую среду. Однако вы можете использовать fifo для добавления новых переменных среды в старый сеанс экрана. Вы можете заполнить этот fifo, когда начнете свой графический сеанс.

#!/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

Запустите этот скрипт в фоновом режиме при входе в систему (он прекратит работу, когда все переменные будут считаны из него).

Теперь вы можете читать с fifo, например, добавить эту функцию в ваш .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
}

так что вы можете в старом сеансе screen

update_session
2

Я реализовал скрипт для этого. Вы можете получить его здесь: https://github.com/DarwinAwardWinner/screen-sendenv

После помещения screen-sendenv.py в ваш $PATH , вы можете использовать следующий фрагмент в вашем .bashrc:

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
}

Чтобы использовать его, просто запустите screen_pushenv прежде чем запускать screen -r чтобы снова подключиться к сеансу экрана. Затем, после подключения с помощью screen -r , вы можете обновить окружение в существующих оболочках с помощью screen_pullenv . Функции tmux выполняют то же самое для tmux, другого терминального мультиплексора, похожего на screen.

0

Это, вероятно, более простое решение (вы решаете). Важной частью является псевдоним, который вызывает функцию savedisplay каждом запуске screen команды. Команды не запускаются автоматически, поэтому их можно поместить в ~/.bashrc вместо чего-то очень специализированного, например ~/.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'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .