Update $DISPLAY in Screen
I’ve been a heavy user of GNU Screen for a number of years. My typical usage is to start a single screen
session and attach to it as I move to different computers, either locally or via SSH. At times I have a need to run X applications from a shell within screen
, but with $DISPLAY
set to the value screen
was initially run with, this tends to not work after it is detached and attached to from a different location.
A few days ago, I came across allsh
, a program that allows commands to be executed in all currently running shells.
I was curious if a similar method might work to fix my $DISPLAY
issue. Ideally, I wanted to be able to attach to the screen
session from any location and have $DISPLAY
updated in all of the bash subprocesses of screen
to properly reflect the desired display.
The following is what I came up with to achieve this.
In ~/.profile
:
TRAPUSR2() { [ -f ~/.screen-display ] && . ~/.screen-display } trap TRAPUSR2 USR2 # set the $DISPLAY variables if the shell is a child of screen if [ "`ps -p $PPID -o comm | tail -1`" == "screen" ] ; then [ -f ~/.screen-display ] && . ~/.screen-display fi
And in a file named attach
, placed somewhere in your $PATH
:
#!/bin/bash echo "DISPLAY=\"$DISPLAY\"" > ~/.screen-display echo "SSH_CLIENT=\"$SSH_CLIENT\"" >> ~/.screen-display echo "SSH_CONNECTION=\"$SSH_CONNECTION\"" >> ~/.screen-display echo "SSH_TTY=\"$SSH_TTY\"" >> ~/.screen-display echo "XAUTHORITY=\"$XAUTHORITY\"" >> ~/.screen-display # detect the pid of screen, but should be smarter if more than one # instance is running if [ `screen -ls | awk -F. '/tached/ { print $1 }' | wc -l` != "1" ] ; then echo "Unable to detect the desired screen session." exit 1 fi SCREEN_PID=`screen -ls | awk '/tached/ { split($1, a, "."); print a[1] }'` # find the pids of the shells that are children of screen BASH_PIDS=`ps -e -o pid,ppid,comm | \ awk '$2 == var1, $3 ~ /bash/ { print $1 }' var1=$SCREEN_PID` kill -USR2 $BASH_PIDS exec screen -d -r
With this setup, start screen
as normal, and then to attach to it from another location, run attach
.