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.