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

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

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

因此,我正在寻找一种方法来修改正在运行的 screen 实例中的环境变量,以便所有后续创建的 screen 窗口都将继承新的环境变量。有办法吗?

答案1

您无法从会话中启动 shell 脚本,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

您可以setenv通过以下方式以交互方式调用命令来更改屏幕过程中的环境变量:Ctrl- A+ :setenv(注意:输入屏幕命令的字符。)系统将提示您输入环境变量名称和值。

请注意(根据其他答案/评论)这会影响(父)屏幕进程,从而影响新创建的屏幕会话,但不会影响您当前的屏幕会话或任何现有的屏幕会话。

如果需要,您可以同时指定环境变量名称和值:Ctrl- A+ :setenv DISPLAY :100。将为新的屏幕会话将 DISPLAY 设置为“:100”。

要删除环境变量,您可以使用“unsetenv”-例如Ctrl- A+:unsetenv DISPLAY

答案3

我已经实现了一个脚本来执行此操作。你可以在这里获取它: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,您可以使用 更新现有 shell 中的环境screen_pullenv。tmux 函数为 tmux(另一个类似于屏幕的终端多路复用器)完成相同的操作。

答案4

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'

相关内容