TIP Using screen

From Gentoo Linux Wiki

Jump to: navigation, search
This article is part of the Tips & Tricks series.
Terminals / Shells Network X Window System Portage System Filesystems Kernel Other

If you do not like unnecessary windows open, or want to get the maximum out of your terminal session, screen will soon be in your .bash_history numerous times. I found GNU Screen's barrier to entry quite high, and I wanted to lower it for my readers.

GNU Screen enables you to run many shell processes in a single terminal. So in one e.g. xterm you can have many bash instances like layers in GIMP or Adobe Photoshop. Even better, you can split your terminal into different regions. Only Ratpoison gives you more bang for your bash!

Contents

[edit] Notation

This document uses the following markup to describe keystrokes:

  • C stands for the Ctrl key
  • - the dash combines two keys which are to be pressed simultaneously
  • C-a is therefore the (standard) escape key for passing the following key as a command to Screen
  • <foo> means pressing the foo-key

[edit] First steps

First you have to install the program (if it isn't already installed). This is as simple as

emerge screen

To start using Screen open a terminal and type screen.

The optional startup message
The optional startup message

Depending on the setup of Screen you may be greeted by a startup message, but Gentoo has this usually disabled in /etc/screenrc with the line startup_message off. More about those settings later.

If you press space or enter you are dropped into a login shell.

One entry in the list of open terminal windows
One entry in the list of open terminal windows

The first sign of Screen successfully running can be discovered by typing C-a " which shows the list of terminals. At the moment there is only one. The Esc key exits that window. Alternatively, use C-a w to list them briefly in the window's title bar.

A new terminal is created by typing C-a c. Typing C-a " again lists the terminals and shows the current one. Press Esc. After creating a new terminal it is useful to press C-a A and enter a name for the terminal.

To create a named terminal directly, use C-a : and type screen <command>.

With C-a n for next or C-a p for previous Screen you can cycle through those windows.


Now comes what I have found is the most useful feature of Screen: If we close the parent terminal Screen continues running! It simply "detaches" and can be accessed again—without any effect on the tasks running. Which makes it ideal for those long compiles Gentoo offers its users....

To detach Screen one can either use the brute-force method of clicking the x in the corner of the window, or the running instance of Screen can be properly detached with C-a d first.

We are now dropped back into the shell that we started with in the beginning. At first we want to check if there is really a Screen-session running. These are listed by screen -ls.

To access this one instance we re-attach with screen -R. VoilĂ , here we go again!

This already explains the basic usage of Screen, and gives us a method to leave compiles running on a remote or local system without the need to keep a terminal open all the time, but Screen has more to offer:

[edit] Regions

Two regions in `Screen`: the newsreader slrn and the IRC client Irssi
Two regions in `Screen`: the newsreader slrn and the IRC client Irssi
I love to keep an eye on #gentoo using my favourite IRC client irssi and read emails/Usenet posts/do whatever without clobbering my monitor.

Similar to vim, which not all of us reportedly prefer, we can use a single terminal window for more than one visible task.

Screen can horizontally split into regions, each holding a different terminal. To open a new region one types C-a S (capital s, please!). To enter that newly created region we have to tab into it: C-a <Tab> Still nothing can be seen, but we can now cycle through our open terminals with C-a n or C-a p. To close a region type C-a X.
A region with focus can be resized with C-a + or C-a - By default this changes the height by 3 lines. Alternatively, you can specify the height to an absolute number by going into Screens command mode. C-a X removes the current region.

[edit] Resizing regions with Commands

Typing C-a : puts Screen into command mode and the status line at the bottom changes. Screen now accepts direct commands and resize 24 makes the currently focused region exactly 24 lines high.

[edit] Problems with Screen being "frozen"?

It is easy to confuse C-a S, which a uses a capital 'S' with C-a s, which uses a lower case 's'. The upper case command causes screen to be horizontally split (that is, with one region on top of the other), while the lower case command causes the parent terminal to freeze. To unfreeze the parent terminal, use the C-a q command.

To remove this command, use the command sequence: bind s. This command can be entered at the colon (':') prompt or in the screen startup file.

What happens is that Screen sends a ^S (xoff) to the screen, which freezes all output. The screen command C-a s is bound to the xoff command. You achieve the same effect in most terminals running bash by typing Ctrl-s. (Type Ctrl-q to undo this effect)

You might have noticed that you can still navigate and use the other windows, and even create new ones after an accidental C-a s. To continue, use the C-a q (which is the xon command). For a proper lock of the session simply type C-a x and only your password gives you access again.

You may also have a problem with Ctrl-z which sends a suspend to the terminal. Type once again to resume and/or turn off altogether with the stty command.

It is also to be noted that when dealing with uppercase commands, you can't type the whole command (i.e C-a S) in a sequence. You must first C-a then Shift-s

[edit] Copying what scrolled by

In a mouse-enabled terminal we can copy and paste text between windows, like a link in irssi to a bash $ opera -newpage http://gentoo.org (which I use to keep my address bar history tidy). If we work outside X in a tty, there is usually no mouse available (unless you are using gpm), but fortunately Screen comes handy even in this situation:

[edit] Scrolling back in Screen

To enter the scrollback mode press C-a <Esc>. When you do this, a notice briefly appears in the terminal's status-bar, which says "Copy mode...". Now, you can scroll up and down in the current terminal using the <PageUp>/<PageDown> keys or the C-u and C-d commands. Althought quite useful by itself, scrollback mode is even more powerful when combined with copy and paste.

If you use scrollback feature a lot and you are using URxvt, then you might want to set:

File: ~/.Xdefaults
URxvt*secondaryScroll: true

This enables you to use Shift-PageUp/Down to back and forth in scroll buffer. Another frequent cause of using scrollback buffer is, when programs like Vim exit they leave their content on the window. To get rid of this behavior use:

File: ~/.screenrc
altscreen on

[edit] Selecting text, copying, pasting

Copying works by selecting a start position and an end position for text to be copied. These are marked with the cursor's current position by pressing the <Space> key. Between two strokes the buffer can be navigated with the keys <h>, <j>, <k>, <l>, they work just as in the editor vim. But on most machines you can also use the <arrow keys> as well if you are not familiar with vim movement commands. And for the fans of emacs this default behavior can be changed in .screenrc. I suggest to consult the man page for the wealth of other movement commands available.

The content of the buffer can then be pasted back into any other Screen window of the current session by typing C-a ].

So imagine you want to open a link pasted in an IRC channel, press C-a <Esc>, move to the beginning of the link, press <Space> and move on to the end for a second <Space>. Now open a new window with C-a c, type lynx C-a ]—and enjoy browsing!

[edit] Advanced copying

One can even access the file system to copy files into Screen, or concatenate selections in a Screen window into a file on the machine where Screen is running on. To copy a funny signature from a Usenet posting set Screen into copy mode with C-a <Esc>, select the text between two <Space> keystrokes and then set a buffer file in the current directory with C-a :bufferfile notes.txt. This file is written into (and overwritten if existing!) by C-a >.

Note that C-a : sets Screen in the command mode and you actually type in Screen's status-bar. If no buffer file is given, Screen uses a default /tmp/screen-exchange, because this feature is primarily meant for exchanging data between Screen users on the same system.

[edit] Direct Access to opened terminals

Besides the somewhat tedious cycling through all terminals that C-a " shows us they are also directly accessible with their numerical identifier: C-a 1 opens the first terminal in the current region, and without modification this work for all single digit identifiers.

In case we lead our computing life completely on the command line and need more than 9 terminals at any time, we can instruct Screen to access double digit ids by editing the file ~/.screenrc.

Add these commands to ~/.screenrc:

File: ~/.screenrc
bind -c selectHighs 0 select 10 #these three commands are 
bind -c selectHighs 1 select 11 #added to the command-class
bind -c selectHighs 2 select 12 #selectHighs
bind - command -c selectHighs   #bind the hyphen to 
                                #command-class selectHighs 

~/.screenrc is normally sourced by Screen at start-up time, but you don't have to restart your session if you make any modifications. Issue the command C-a :source .screenrc to re-source your settings.

Now C-a - 0 opens the 10th terminal under Screen's control (if existing).

[edit] More useful settings in .screenrc

First thing I add is

vbell off

which makes stupid attempts of tab-completion more bearable, these and other errors are then shown in xterm's heading bar instead of making the terminal blinking and flashing.

Screen can also be told to open several terminals at startup, and even assign more meaningful names to those terminals in e.g. the list of terminals shown by C-a " . The following examples explain the syntax:

File: ~/.screenrc
screen -t E-Mail     2   mutt -y
screen -t irssi      3   irssi
screen -t mp3blaster 4
stuff "mp3blaster\015"
screen -t news       5   slrn  -h  news.individual.net -f /home/cprior/.jnewsrc
screen -t rss		 6   raggle
screen -t root       1   su -

These commands open a second window with the title E-Mail and the mailbox view of Mutt. The reason I put the first window at the end is because I like to open a root shell for whatever administrative tasks and want Screen to dump me to the password request. Otherwise I would end in raggle and had toC-a n to it. Other ways of preselecting windows are explained in the man page for the option -p.

The different notation for mp3blaster keeps that terminal alive after quitting mp3blaster: Exit that mp3 player and you are dropped back to a shell.

Any other file can be used instead of ~/.screenrc by pointing Screen at it with the -c option, e.g. screen -c /dev/null which I use in the rare case I want to start Screen as if no .screenrc existed.

[edit] More screenrc tweaks

[edit] Change escape sequence

I love screen, but hate using the C-a escape sequence because I really dislike using the control key so much (I am a VIM user, can you tell?). Therefore, I remap the escape to use the backtick "`" instead. So everytime the screen documentation says C-a, you use the backtick instead. When I really need a backtick I just hit it twice. This works well since I really only use the backtick for scripting. To do this just add this line to your ~/.screenrc file:

File: ~/.screenrc
escape ``

If you want to have the backtick toggle between the two most recent windows as C-a C-a would, you should instead have something similar to the following in your ~/.screenrc:

File: ~/.screenrc
escape `e

This will bind the backtick character to ` e and allow ` ` to toggle windows. Note that this will clobber whatever ` e was previously bound to. 'e' is chosen here as it is not used by default.

Please note that using the backtick can cause problems with mouse-scrolling, as the wheel's escape code can have a backtick in it.

Serious programmers may find it quite inconvenient to use the backtick, so feel free to experiment with other characters or simply use the default setting.


Emacs uses C-a for beginning-of-line. It is also the command key for GNU Screen, which causes the problem of muscle memory impedence matching. This can be avoided with the following, which binds the command key of GNU screen to C-o.

File: ~/.screenrc
escape ^Oo

C-t is also a popular choice, although this will conflict with the transpose function. Also C-t is the default for the Ratpoison Window Manager. (which is very Screen-like and works well with Emacs and Screen)

[edit] Tab-bar

Screen using "tabs" to display open windows
Screen using "tabs" to display open windows

The other thing I like to do is show a "tab-bar." This displays a strip along the bottom with the names and numbers of the different windows you have open. It also has a clock in the lower right since it was just dead space anyway. Look at the screen shot to see how it looks while running in Eterm. This really helps in keeping track of what screens you have open at a glance. You can add this functionality by adding the following lines to your ~/.screenrc file.

File: ~/.screenrc
#change the hardstatus settings to give an window list at the bottom of the                                                                        
#screen, with the time and date and with the current window highlighted                                                                            
hardstatus alwayslastline                                                                                                                          
hardstatus string '%{= mK}%-Lw%{= KW}%50>%n%f* %t%{= mK}%+Lw%< %{= kG}%-=%D %d %M %Y %c:%s%{-}'

You can check this other one too :

hardstatus string '%{= kG}%-Lw%{= kW}%50> %n%f* %t%{= kG}%+Lw%< %{= kG}%-=%c:%s%{-}'

A _very_ nice one IMHO is this one with hostname, centered tabs and redmarked active windows:

hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B} %d/%m %{W}%c %{g}]'

You can play with the values in the %{= xx} fields to change the colors. See the screen manpage under "STRING ESCAPES" for more details.

A nice variation of the above, which also shows the load average:

hardstatus string '%{gk}[ %{G}%H %{g}][%= %{wk}%?%-Lw%?%{=b kR}(%{W}%n*%f %t%?(%u)%?%{=b kR})%{= kw}%?%+Lw%?%?%= %{g}][%{Y}%l%{g}]%{=b C}[ %m/%d %c ]%{W}'

You can use the backtick command to insert custom text into the tab bar. This program must return a single line, no carriage returns, that will fit comforably in what space you have available on your tab bar.

backtick 1 60 60 /some/program hardstatus string "%1`"

[edit] auto renaming the "tabs"

make your bash prompt have a certain character at the end, by appending this to your PS1 like so:

File: ~/.bashrc
export PS1="\u@\h \w"'\[\033k\033\\\]\$ '

screen needs to know about this too, so add this to your .screenrc

File: ~/.screenrc
shelltitle "$ |bash"

[edit] More about attaching to Screen sessions

A remote Screen session is sometimes not properly detached when e.g. the local xterm was killed or the net connection died. We then see the session as still attached when listing them with screen -ls

To attach to this session we can either use its session name or tell Screen to detach it first—which is the easiest way if there is only one session existing: screen -DR To attach a specific session out of a list returned by screen -ls, like -r [pid.tty.host], where [pid.tty.host] is e.g. 13539.pts-0.hostname, use screen -r 13539.pts-0.hostname although you only have to type the first unique number, in this example typing screen -r 1 would attach to the 13539.pts-0.hostname screen session.

[edit] Naming Sessions

Naming Screen sessions can help you remember them without having to use ls and type the pid. Use screen -S foo to create a session with the name foo and screen -r foo to re-connect to the session with the name foo.

The following script can be used to list the existing sessions and reattach to one using the index number:

#!/bin/bash


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

if [[ "$res" == "0" ]]
then
        echo "  No existing SCREEN session to reattach to..."
        exit
fi

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

#if first argument is not specified, script will ask for number of screen

if [ -z $1 ]
then
        echo -n "  Reattach to session: "
        read session
else
        session=$1
fi


#attach to specified session
linenum=0
name=`screen -ls | sed -ne 's/[[:space:]]//' -ne 's/\((Attached)\|(Detached)\)// p' |
while read line
do
 let "linenum += 1"
 if [[ "$linenum" -eq "$session" ]]
 then
        echo $line
        break
 fi
done`

if [[ "$name" != "" ]]
then
   screen -d -r "$name"
else
   echo "  Could not reattach to '$session'"
fi

[edit] Multi-user mode

Useful for collaborative install sessions is the multiuser mode of Screen. Just execute screen -x to attach to a Screen multiple times.

NOTE: Gentoo disabled this by default on older ebuilds of Screen because it required Screen to be setuid root. If you have trouble try updating your copy of Screen.

For more details see HOWTO Snoop terminal session#Screen

[edit] Monitoring for silence or activity

An emerge -uDv world in one of many active windows might lead to numerous C-a n C-a p: «Is it ready yet»? But Screen has a feature for notifying us in whatever session-window we might currently work.

The command C-a _ switches into the monitoring mode for 15 seconds of silence, which triggers a notification in xterm's status area. A second repitition of this command switches the monitoring off. So when our compile finishes, we will be told so even in another session-window.

On the contrary, C-a M sets Screen into monitoring for all activity. I use the MSN command line client pebrot occasionally, and always set its window to notify me when e.g. a join message occurs.

[edit] Starting Screen upon ssh-login

Although not necessarily a feature of Screen, we can spare us an additional exit to logout remotely by connecting with ssh -t user@host screen -RD This will also detach the running session if necessary and reattach to it again. (If none exist, a new one is created. I have aliased Screen in my .bashrc to this variation for the sake of convenience.)

[edit] Quick walk-through

CommandEffect
screenLogin and start a Screen session right away
C-a "Show list of terminals managed by Screen; Here: only one
EscClose the list window
C-a cCreate a new terminal window
C-a "The list of terminals now shows two entries
EscClose the list window
lsshow the directory contents in this window
C-a preturn to the previous, first window
ping forums.gentoo.orgDo something in this window, too
C-a cCreate another window
C-a SSplit the term vertically into two regions
C-a XKill the current region
C-a <Tab>Focus the newly created region
C-a -Resize this region and make it 3 lines smaller
C-a 1Show the first window in this region
C-a <Tab>Move the focus back to the upper region
C-a dDetach the Screen session
 open a xterm
screen -DRlogin again and make Screen re-attach (R) to the first session found, after detaching (D) the session first, if necessary (which it wasn't)

[edit] Seeing is believing

An animation of Screen's usage
An animation of Screen's usage

This animated .gif shows most basic commands in a sequence of 50 pictures. This is a transcript of all typed keystrokes:

xterm<Enter>
screen<Enter>
C-a "
<Esc>
C-a c
C-a "
<Esc>
ping forums.gentoo.org<Enter>
C-a n
ls -la<Enter>
C-a S
C-a <Tab>
C-a 1
C-a <Tab>
C-a +
C-a :resize 18<Enter>
C-a x
password
C-a d
screen -ls<Enter>
screen -R<Enter>
printf 'GET / HTTP/1.0\n\n' | telnet forums.gentoo.org 80<Enter>
C-a <Esc>
<PageUp>
<ArrowKeys>
<Space>
<ArrowKeys>
<Space>
C-a c
lynx C-a ]

[edit] Exiting Screen

One way to close a Screen session is to exit all terminal sessions you are running inside, one after the other. After the last exit inside Screen you will get [screen is terminating] as a confirmation that your Screen session has ended.

However, a simpler and faster way to do the same thing is to use Screen's quit command.

C-a :quit

This will kill all programs running inside the current Screen session and exit the session. If you use this command frequently, it may be useful to create a keybinding in your configuration file:

File: ~/.screenrc
# bind F10 to Screen's quit command
bindkey -k k; quit

See the "INPUT TRANSLATION" section of the Screen manual for details on how to bind function keys (e.g, F1, F2, ...).

[edit] Common problems

[edit] Can't open display

If the Screen was started from text console or other graphical session you may get an error: "Error: Can't open display:" while trying to launch some graphical application. You must set DISPLAY variable to proper value

$ export DISPLAY=":0"

[edit] Control a Screen within a Screen

Sometimes it can happen that you accidently attach a screen from within a screen. So you try to detach the last one, the problem is that your first screen will react to the C-a d. To control a screen within a different screen you have to first hit C-a and then do what you want to do with the other screen, without the C-.

Like so:

Command Effect
screen Start screen session 1
screen -r Attach screen session 2 within screen session 1
C-a Tell screen session 1 to wait for a command
a d The 'a' tells the second session to listen, and then to detach

Using this method, one can control any number of nested screen sessions within other screen sessions. It just becomes a bear to keep all of them straight in your head. For some of us this isn't a problem, since for example I admin at least two machines at a time and both have existing screen sessions running. Instead of connecting to each one separately, I run another screen session locally, and make several terminals for each machine I'm using. So let's say that on terminal 1 we have machine A and on terminal 2 we have machine B. We've established ssh sessions and reattached the remote screen instances.

Now within the local screen session we can control machine A by switching to our local terminal 1, C-a 1, then getting a list of remote terminals with C-a a ". To detach from the remote screen instance, simply use C-a a d. From there you can see how you just have to keep adding an additional "a" meta-command character for every nested screen instance.

Quiz: how many nested sessions do we have if we just used this command: C-a a a a a 5

For fun try out how many nested screen instances you can keep track of :) Hint: This is where naming your sessions becomes really useful!

Answer to the quiz: 4.


On the other hand it's most probably just more feasible to use a terminal that supports tabs (like gnome-terminal) or a window manager that supports tabs generically (like fluxbox or ion) to achieve a similar effect locally and use screen just for remote sessions.

[edit] Uncommon problems

[edit] Socket Missing

Sometimes the socket of a still-running screen can be destroyed, though the actual process and all of it's child processes are still running. screen -list will display "No Sockets found in /tmp/uscreens/.." Some handy instructions for how to recover from this (and a few other uncommon problems) at here: http://www4.informatik.uni-erlangen.de/~jnweiger/screen-faq.html#MISC about 2/3 of the way down.


Q: For some unknown reason, the fifo in /tmp/screens/S-myname is gone, and i can't resume my screen session. Is there a way to recreate the fifo?

A: Screen checks the fifo/socket whenever it receives a SIGCHLD signal. If missing, the fifo/socket is recreated then. If screen is running non set-uid the user can issue a 'kill -CHLD screenpid' directly (it is -CHILD on some systems). Screenpid is the process-id of the screen process found in a 'ps -x' listing. But usually this won't work, as screen should be installed setuid root. In this case you will not be able to send it a signal, but the kernel will. It does so, whenever a child of screen changes its state. Find the process-id (shellpid below) of the "least important" shell running inside screen. The try 'kill -STOP shellpid'. If the fifo/socket does not reappear, destroy the shell process. You sacrify one shell to save the rest. If nothing works, please do not forget to remove all processes running in the lost screen session.

[edit] See also

MAN screen

[edit] External Links

Personal tools