Difference between revisions of "WorkingOnServers/DisplayEnvironmentTricks"

From mn/geo/geoit
Jump to: navigation, search
(A script for keeping track of screens)
 
(13 intermediate revisions by 2 users not shown)
Line 1: Line 1:
=Introduction=
+
= Introduction =
  
 
Using IPython via ssh with X-forwarding is a really great way to work, but it can be a pain with the DISPLAY settings. The tricks outlined below have been really helpful for me and are now a part of my standard 'workflow'. For the most part, I assume Ubuntu (or some 'deb' package OS variant) and bash in my descriptions below. YMMV.
 
Using IPython via ssh with X-forwarding is a really great way to work, but it can be a pain with the DISPLAY settings. The tricks outlined below have been really helpful for me and are now a part of my standard 'workflow'. For the most part, I assume Ubuntu (or some 'deb' package OS variant) and bash in my descriptions below. YMMV.
  
=A way to preserve your DISPLAY environment=
+
= A way to preserve your DISPLAY environment =
  
When working via ssh (and X forwarding) on IPython, sometimes your DISPLAY environment variable gets mangled. One approach to deal with this is outlined below, but recently I found a new approach.
+
When working via ssh (and X forwarding) on IPython, sometimes your '''<code>$DISPLAY</code>''' environment variable gets mangled. One approach to deal with this is outlined below, but recently I found a new approach.
  
There is a program called xpra which creates a virtual monitor (x  
+
There is a program called xpra which creates a virtual monitor (x server) to which you can point your DISPLAY variable.
server) to which you can point your DISPLAY variable.
 
  
You can start a screen session with the DISPLAY setting pointing to this  
+
You can start a screen session with the '''<code>DISPLAY</code>''' setting pointing to this virtual display. Then when you run IPython (inside screen) anything sent to X-display is sent to the virtual environment. You can attach and detach to this environment and your GUIs / matplotlib windows, etc will remain alive.
virtual display. Then when you run IPython (inside screen) anything sent  
 
to X-display is sent to the virtual environment. You can attach and  
 
detach to this environment and your GUIs / matplotlib windows, etc will  
 
remain alive.
 
  
 
To install xpra:
 
To install xpra:
 
+
<pre>sudo apt-get install xpra
<pre>
 
sudo apt-get install xpra
 
 
</pre>
 
</pre>
 
 
Then a session:
 
Then a session:
  
 
First, start a screen session pointing to a virtual display
 
First, start a screen session pointing to a virtual display
<pre>
+
<pre>xpra start&nbsp;:100
xpra start :100
 
 
DISPLAY=:100 screen
 
DISPLAY=:100 screen
 
</pre>
 
</pre>
 
+
Now you've started screen and should be "inside" screen with all your X display sent to&nbsp;:100. You can start Ipython in the screen session:
Now you've started screen and should be "inside" screen with all your X display sent to :100. You can start Ipython in the screen session:
+
<pre>ipython
 
 
<pre>
 
ipython
 
 
</pre>
 
</pre>
 
 
In another terminal, attach to the xpra display to 'see' the X programs:
 
In another terminal, attach to the xpra display to 'see' the X programs:
 
+
<pre>xpra attach&nbsp;:100
<pre>
 
xpra attach :100
 
 
</pre>
 
</pre>
 +
You can detach from both these sessions, and they'll keep running, get home or wherever... reattach to screen and also reattach to your xpra virtual display. Good luck!
  
You can detach from both these sessions, and they'll keep running, get
+
= Another approach for working with SSH and GNU screen (helpful for Ipython) =
home or wherever... reattach to screen and also reattach to your xpra
 
virtual display. Good luck!
 
 
 
 
=Another approach for working with SSH and GNU screen (helpful for Ipython)=
 
  
 
Often you'll want to ssh to a server, start a job and leave. Knowing that you want the job to stay alive after you log out, you can just use:
 
Often you'll want to ssh to a server, start a job and leave. Knowing that you want the job to stay alive after you log out, you can just use:
 
+
<pre>nohup myjob.sh > nohup_output.nh &
<pre>
 
nohup myjob.sh > nohup_output.nh
 
 
</pre>
 
</pre>
 
+
But sometimes you'd rather have an actual term or shell session stay alive. This is often the case when working with IPython. The problem is that your '''<code>DISPLAY</code>''' environment variable may change, so that when you log into the machine later, what screen thinks is the present '''<code>DISPLAY</code>''' variable will no longer be current and you'll get errors.
But sometimes you'd rather have an actual term or shell session stay alive. This is often the case when working with IPython. The problem is that your $DISPLAY environment variable may change, so that when you log into the machine later, what screen thinks is the present $DISPLAY variable will no longer be current and you'll get errors.
 
  
 
My workaround for this has been the following:
 
My workaround for this has been the following:
  
1 On the ''host'' machine, that is the one you are logging into, in your <code>.bash_profile </code> (which gets read when you log in via ssh) you should add the line:
+
1 On the ''host'' machine, that is the one you are logging into, in your '''<code>.bash_profile</code>''' (which gets read when you log in via ssh) you should add the line:
  <pre>
+
<pre>   echo "export DISPLAY=$DISPLAY" > .display.`whoami`.`hostname`
  echo "export DISPLAY=$DISPLAY" > .display.`whoami`.`hostname`
 
 
   </pre>
 
   </pre>
 
+
2 Again, on your ''host'' machine,make sure the following is in your '''<code>.bashrc</code>''':
2 Again, on your ''host'' machine,make sure the following is in your .bashrc:
+
<pre>   ## set the prompt command to read the .disply file
  <pre>
 
  ## set the prompt command to read the .disply file
 
 
   export PROMPT_COMMAND=". ~/.display.`whoami`.`hostname`"
 
   export PROMPT_COMMAND=". ~/.display.`whoami`.`hostname`"
 
   </pre>
 
   </pre>
 +
<br/>What is happening here is that every time you log in, the '''<code>.bash_profile</code>''' file creates a new file in your home directory, specific to your user, and the hostname. Whenever you log out and log back in, that file is updated with the appropriate DISPLAY information. In the '''<code>.bashrc</code>''' file, we've created a PROMPT_COMMAND that will read that file every time you hit return in your shell. This can cause some annoyances if the file does not exist, for example if you use the 'su' command to become another user. However, overall it works quite well, such that when you return to a running ''screen'' session, the DISPLAY variable will be updated and you'll be able to send X-display windows back to your client machine.
  
 
+
= A script for keeping track of screens =
What is happening here is that everytime you log in, the .bash_profile file creates a new file in your home directory, specific to your user, and the hostname. Whenever you log out and log back in, that file is updated with the appropriate DISPLAY information. In the .bashrc file, we've created a PROMPT_COMMAND that will read that file everytime you hit return in your shell. This can cause some annoyances if the file does not exist, for example if you use the 'su' command to become another user. However, overall it works quite well, such that when you return to a running ''screen'' session, the DISPLAY variable will be updated and you'll be able to send X-display windows back to your client machine.
 
 
 
=A script for keeping track of screens=
 
  
 
Often you may have several <code>screen</code> sessions running. It is recommended to start <code>screen</code> with the following command:
 
Often you may have several <code>screen</code> sessions running. It is recommended to start <code>screen</code> with the following command:
<pre>
+
<pre>screen -S my_description
screen -S my_description
 
 
</pre>
 
</pre>
 +
Where ''my_description'' is some string that has meaning to you as a 'session' identifier. If only one <code>screen</code> session is running then simply <code>screen -r</code> will reconnect. However, if you have more, things can get complicated. The following script is helpful in such a case:
  
Where ''my_description'' is some string that has meaning to you as a 'session' identifier. If only one <code>screen</code> session is running then simply <code>screen -r</code> will reconnect. However, if you have more, things can get complicated. The following script is helpful in such a case:
+
<pre>
<source lang='bash'>
 
 
#!/bin/bash
 
#!/bin/bash
 +
  
 
# filters the screen -ls output to show the sesssions
 
# filters the screen -ls output to show the sesssions
sessions=`screen -ls | sed -ne 's/[[:space:]]//' -ne 's/\((Attached)\|(Detached)\|(Multi, detached)\|(Multi, attached)\)// p'`
+
sessions=`screen -ls | sed -ne 's/[[:space:]]//' -ne 's/\((Attached)\|(Detached)\|(Multi, detached)\|(Multi,           attached)\)// p'`
 
#echo $sessions
 
#echo $sessions
 
#echo $sessions | wc -w
 
#echo $sessions | wc -w
Line 110: Line 83:
 
             #attach to specified session
 
             #attach to specified session
 
             linenum=0
 
             linenum=0
             name=`screen -ls | sed -ne 's/[[:space:]]//' -ne 's/\((Attached)\|(Detached)\|(Multi, detached)\|(Multi, attached)\)// p' |
+
             name=`screen -ls | sed -ne 's/[[:space:]]//' -ne 's/\((Attached)\|(Detached)\|(Multi, detached)\|(Multi,   attached)\)// p' |
 
             while read line
 
             while read line
 
             do
 
             do
Line 121: Line 94:
 
             done`
 
             done`
 
             shrtname=`echo $name | sed -e 's/[[:space:]]//' -e 's/(.*)//' -e 's/\t//g'`
 
             shrtname=`echo $name | sed -e 's/[[:space:]]//' -e 's/(.*)//' -e 's/\t//g'`
 
 
 
             echo "Reattaching to: " $shrtname
 
             echo "Reattaching to: " $shrtname
 
             if [[ "$name" != "" ]]; then
 
             if [[ "$name" != "" ]]; then
Line 148: Line 119:
 
                         screen -Ax "$shrtname"
 
                         screen -Ax "$shrtname"
 
                     then
 
                     then
                        echo "Hope that was fun!"
+
                     fi
                    else
+
                 fi
                        echo "Trying to Force connection"
 
                        screen -D -r "$shrtname"
 
                     fi
 
                 fi
 
 
             else
 
             else
 
               echo "Could not reattach to $session"
 
               echo "Could not reattach to $session"
             fi
+
             fi
 
         else
 
         else
 
             echo " Have fun..."
 
             echo " Have fun..."
         fi
+
         fi
 
else
 
else
 
         echo "  No existing SCREEN session to reattach to..."
 
         echo "  No existing SCREEN session to reattach to..."
  
 
fi
 
fi
 
</source>
 
 
 
Save this file in your $HOME/bin directory as 'screenlist' and make it executable: <code>chmod +x screenlist</code>. Then at the command prompt you can type:
 
<pre>
 
[user@host ~]$screenlist
 
 
</pre>
 
</pre>
 
+
<br/>Save this file in your $HOME/bin directory as 'screenlist' and make it executable: <code>chmod +x screenlist</code>. Then at the command prompt you can type:
 +
<pre>[user@host ~]$screenlist
 +
</pre>
 
and you should get some output similar to:
 
and you should get some output similar to:
<pre>
+
<pre> CURRENT SESSIONS
  CURRENT SESSIONS
 
 
   ------------------------
 
   ------------------------
 
     1  3841.coding    (09/26/2011 11:35:01 PM)
 
     1  3841.coding    (09/26/2011 11:35:01 PM)
Line 185: Line 146:
  
 
</pre>
 
</pre>
 +
[[Category:Tools]]<br/>[[Category:UioNetwork]]

Latest revision as of 23:32, 16 October 2015

Introduction

Using IPython via ssh with X-forwarding is a really great way to work, but it can be a pain with the DISPLAY settings. The tricks outlined below have been really helpful for me and are now a part of my standard 'workflow'. For the most part, I assume Ubuntu (or some 'deb' package OS variant) and bash in my descriptions below. YMMV.

A way to preserve your DISPLAY environment

When working via ssh (and X forwarding) on IPython, sometimes your $DISPLAY environment variable gets mangled. One approach to deal with this is outlined below, but recently I found a new approach.

There is a program called xpra which creates a virtual monitor (x server) to which you can point your DISPLAY variable.

You can start a screen session with the DISPLAY setting pointing to this virtual display. Then when you run IPython (inside screen) anything sent to X-display is sent to the virtual environment. You can attach and detach to this environment and your GUIs / matplotlib windows, etc will remain alive.

To install xpra:

sudo apt-get install xpra

Then a session:

First, start a screen session pointing to a virtual display

xpra start :100
DISPLAY=:100 screen

Now you've started screen and should be "inside" screen with all your X display sent to :100. You can start Ipython in the screen session:

ipython

In another terminal, attach to the xpra display to 'see' the X programs:

xpra attach :100

You can detach from both these sessions, and they'll keep running, get home or wherever... reattach to screen and also reattach to your xpra virtual display. Good luck!

Another approach for working with SSH and GNU screen (helpful for Ipython)

Often you'll want to ssh to a server, start a job and leave. Knowing that you want the job to stay alive after you log out, you can just use:

nohup myjob.sh > nohup_output.nh &

But sometimes you'd rather have an actual term or shell session stay alive. This is often the case when working with IPython. The problem is that your DISPLAY environment variable may change, so that when you log into the machine later, what screen thinks is the present DISPLAY variable will no longer be current and you'll get errors.

My workaround for this has been the following:

1 On the host machine, that is the one you are logging into, in your .bash_profile (which gets read when you log in via ssh) you should add the line:

   echo "export DISPLAY=$DISPLAY" > .display.`whoami`.`hostname`
  

2 Again, on your host machine,make sure the following is in your .bashrc:

   ## set the prompt command to read the .disply file
   export PROMPT_COMMAND=". ~/.display.`whoami`.`hostname`"
  


What is happening here is that every time you log in, the .bash_profile file creates a new file in your home directory, specific to your user, and the hostname. Whenever you log out and log back in, that file is updated with the appropriate DISPLAY information. In the .bashrc file, we've created a PROMPT_COMMAND that will read that file every time you hit return in your shell. This can cause some annoyances if the file does not exist, for example if you use the 'su' command to become another user. However, overall it works quite well, such that when you return to a running screen session, the DISPLAY variable will be updated and you'll be able to send X-display windows back to your client machine.

A script for keeping track of screens

Often you may have several screen sessions running. It is recommended to start screen with the following command:

screen -S my_description

Where my_description is some string that has meaning to you as a 'session' identifier. If only one screen session is running then simply screen -r will reconnect. However, if you have more, things can get complicated. The following script is helpful in such a case:

#!/bin/bash


# filters the screen -ls output to show the sesssions
sessions=`screen -ls | sed -ne 's/[[:space:]]//' -ne 's/\((Attached)\|(Detached)\|(Multi, detached)\|(Multi,           attached)\)// p'`
#echo $sessions
#echo $sessions | wc -w
res=`echo "$sessions" | wc -w`

if [[ "$res" != "0" ]]
then

        echo ''
        echo "  CURRENT SESSIONS"
        echo "  ------------------------"
        #screen -ls | sed -ne 's/[[:space:]]//' -ne 's/\((Attached)\|(Detached)\)// p' | cat -n
        echo "$sessions" | cat -n
        echo "  ------------------------"
        echo ''

        #prompt for the session to join
        echo -n "  Reattach to session, or ENTER for None: "
        read session

        if [[ $session != 0 ]]
        then

            #attach to specified session
            linenum=0
            name=`screen -ls | sed -ne 's/[[:space:]]//' -ne 's/\((Attached)\|(Detached)\|(Multi, detached)\|(Multi,   attached)\)// p' |
            while read line
            do
             let "linenum += 1"
             if [[ "$linenum" -eq "$session" ]]
             then
                    echo $line
                    break
             fi
            done`
            shrtname=`echo $name | sed -e 's/[[:space:]]//' -e 's/(.*)//' -e 's/\t//g'`
            echo "Reattaching to: " $shrtname
            if [[ "$name" != "" ]]; then
                if  
                    #echo $shrtname
                    screen -r "$shrtname"
                then
                    echo -n " Bye bye screen.. Exit?[y] "
                    read nbye
                        if [[ "$nbye" == "" ]]
                        then 
                            exit
                        else
                            goodbye=$nbye
                        fi  
                        if [[ "$goodbye" == "y" ]]
                        then
                            exit
                        else
                            echo "What's next?"
                        fi  
                else
                    if  
                        # try multiuser connect
                        screen -Ax "$shrtname"
                    then
                    fi
                fi
            else
               echo "Could not reattach to $session"
            fi
        else
            echo " Have fun..."
        fi
else
        echo "  No existing SCREEN session to reattach to..."

fi


Save this file in your $HOME/bin directory as 'screenlist' and make it executable: chmod +x screenlist. Then at the command prompt you can type:

[user@host ~]$screenlist 

and you should get some output similar to:

  CURRENT SESSIONS
  ------------------------
     1  3841.coding     (09/26/2011 11:35:01 PM)
     2  3791.Ipython    (09/26/2011 11:34:42 PM)
     3  17716.test3     (09/26/2011 10:12:15 PM)
  ------------------------

  Reattach to session, or ENTER for None: