Archive

Posts Tagged ‘ssh’

Update $DISPLAY in Screen

December 12th, 2009 Comments off

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.

Tags: , ,