更新屏幕会话环境变量以反映新的图形登录?

Rya*_*son 21 linux xorg environment-variables dbus gnu-screen

我使用 linux,我喜欢在单个屏幕会话中完成我所有的命令行工作,这样我就可以重新启动图形登录等,而不会丢失我的终端。但是,当我注销并重新进入我的图形会话时,这会更改我的所有会话环境变量,例如 DBus 会话。这意味着再次登录后,我的屏幕会话现在具有旧的(错误的)环境变量。因此,现在当我尝试从我的屏幕会话启动图形程序时,它们最多会发出关于无法连接到会话总线的警告。最糟糕的是,它们无法完全启动。

所以,我正在寻找一种在 screen 的运行实例中修改环境变量的方法,以便所有随后创建的 screen 窗口都将继承新的环境变量。有没有办法做到这一点?

Ben*_*ier 8

您不能从screen会话中启动 shell 脚本,因为它会继承旧环境。但是,您可以使用 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
Run Code Online (Sandbox Code Playgroud)

在登录时在后台启动该脚本(它只会在从中读取所有变量时终止)。

现在您可以从 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
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以在你的旧screen会话中

update_session
Run Code Online (Sandbox Code Playgroud)


Rya*_*son 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
}
Run Code Online (Sandbox Code Playgroud)

要使用它,只需screen_pushenv在运行screen -r重新连接到屏幕会话之前运行即可。然后,在附加 后screen -r,您可以使用 更新现有 shell 中的环境screen_pullenv。tmux 函数为 tmux(另一个类似于 screen 的终端多路复用器)完成同样的事情。