我使用 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'