Extending GNU Screen - Adding a taskbar

One of the biggest drawbacks of GNU Screen is that you don’t see an overview of your virtual terminals in most standard configurations. But that can be easily changed. My screen now looks like this:

Bild / Screenshot eines gepimpten und aufgemotzten screen-Terminals

Screenshot of extented screen with taskbar

You can clearly see which programs are running and you have a good overview. The other goodies like cpu load display and the clock is also very practical.

The global configuration file /etc/screenrc already has some minor tweaks (Depending on your distribution). If you only want the taskbar for a particular user, than the local .screenrc in your home directory is the file to edit.

The heart of my screen configuration is:


backtick 1 0 0 /usr/bin/cpuusage
hardstatus alwayslastline
hardstatus string '%{= kG} %{G}%H %{g}[%= %{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}] %1`%% CPU %{W}%c %{g}’

With “backtick” a command-directive (1 here - must be a number) is noted. The “0 0″ then means that whenever a new output from the program is produced, screen stores the last line of output. “Hardstatus” is for the taskbar and each % directive is for special purposes. With `% 1 for example the last line of the backtick command is printed. For all the other directives better read the GNU screen-manpage

The cpuusage-script looks like this:

  1. #!/bin/bash
  2. awk ‘BEGIN {file = "/proc/stat";while (a==a) {getline < file;u=$2-up;s=$3-sp;n=$4-np;i=$5-ip;printf ("%2.1f\n"),(u+s)/(u+s+n+i)*100;up=$2;sp=$3;np=$4;ip=$5;close(file);system("sleep 1")}}’

This awk-oneliner uses the information from /proc/stat to calculate the cpuload for one second. That is supported on all unixes with proc support (Mac OS X has no proc).

What’s missing now, is dynamic window titles. In the previous configuration, all titles are set to “n * bash”, we had to change the titles manually.

With a special escape-sequence, the title can be set from the console. The screen manpage explains the procedure:


The default name for all shell windows can be set with the "shelltitle"
command in the .screenrc file, while all other windows are created with
a "screen" command and thus can have their name set with the -t option.
Interactively, there is the title-string escape-sequence
(kname\) and the “title” command (C-a A). The former can be
output from an application to control the window’s name under software
control, and the latter will prompt for a name when typed. You can
also bind pre-defined names to keys with the “title” command to set
things quickly without prompting.

Finally, screen has a shell-specific heuristic that is enabled by set-
ting the window’s name to “search|name” and arranging to have a null
title escape-sequence output as a part of your prompt. The search por-
tion specifies an end-of-prompt search string, while the name portion
specifies the default shell name for the window. If the name ends in a
‘:’ screen will add what it believes to be the current command running
in the window to the end of the window’s shell name (e.g. “name:cmd”).
Otherwise the current command name supersedes the shell name while it
is running.

Here’s how it works: you must modify your shell prompt to output a
null title-escape-sequence (k\) as a part of your prompt.
The last part of your prompt must be the same as the string you speci-
fied for the search portion of the title. Once this is set up, screen
will use the title-escape-sequence to clear the previous command name
and get ready for the next command. Then, when a newline is received
from the shell, a search is made for the end of the prompt. If found,
it will grab the first word after the matched string and use it as the
command name. If the command name begins with either ‘!’, ‘%’, or ‘^’
screen will use the first word on the following line (if found) in
preference to the just-found name. This helps csh users get better
command names when using job control or history recall commands.

My shellprompt looks like this:


server1 pastacode #

That means, all my commands are typed in after the #. So, I have to add this to my .shellrc :


#dynamic title
shelltitle '# |bash'

Screen now looks for a # when it gets the escape-sequence. “| Bash” means that the default title is “Bash”. We now only need the escape sequence in our promt; that can be customized (in Bash) with the PS1 variable. To do this we will either edit the /etc/bashrc (for any user) or the local .bashrc in our home directory. My .bashrc looks like this:

  1. export EDITOR=/usr/bin/vi
  2.  
  3. # Set the screen title
  4. case $TERM in
  5. screen*)
  6. # This is the escape sequence ESC k \w ESC \
  7. #Use path as titel
  8. #SCREENTITLE=’\[\ek\w\e\\\]‘
  9. #Use program name as titel
  10. SCREENTITLE=‘\[\ek\e\\\]‘
  11. ;;
  12. *)
  13. SCREENTITLE=
  14. ;;
  15. esac
  16.  
  17.  
  18. PS1="${SCREENTITLE}${PS1}"

The PS1 is altered to add the screen escape-sequence, but only when we are in screen. In my file, you can actually choose between two versions: either the current path is the dynamic title, or the program name, although I prefer the latter. Unfortunately viewing both seems to be not a trivial thing.

So I hope the whole thing works for you - for suggestions, better ideas - write a comment!

Last but not least my complete .screenrc:

  1. #no bells and startup messages
  2. startup_message off
  3. vbell off
  4.  
  5. #10000 lines scrollback buffer
  6. defscrollback 10000
  7. #no login
  8. deflogin off
  9.  
  10. # Default shell
  11. shell bash
  12.  
  13. #Timeout for displaying messages
  14. msgwait 1
  15. activity "         Activity has appeared in window      %n - %t"
  16.  
  17. #taskbar
  18. backtick 1 0 0 /usr/bin/cpuusage
  19. hardstatus alwayslastline
  20. hardstatus string ‘%{= kG} %{G}%H %{g}[%= %{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}] %1`%% CPU %{W}%c %{g}’
  21.  
  22. #dynamic title
  23. shelltitle ‘# |bash’
  24.  
  25. #When your ssh connection dies, screen is autodetached
  26. autodetach on
  27.  
  28. #Nice 256 term colors
  29. attrcolor b ".I"
  30. termcapinfo xterm ‘Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm’

And the cpuusage script:

  1. #!/bin/bash
  2. awk ‘BEGIN {file = "/proc/stat";while (a==a) {getline < file;u=$2-up;s=$3-sp;n=$4-np;i=$5-ip;printf ("%2.1f\n"),(u+s)/(u+s+n+i)*100;up=$2;sp=$3;np=$4;ip=$5;close(file);system("sleep 1")}}’

Sources:

The pages below helped me alot:

http://listserv.ccjclearline.com/pipermail/kwlug-disc/2006-November/002132.html
http://b79.net/code/screenrc
http://www.mediacollege.com/cgi-bin/man/page.cgi?topic=screen

3 Comments

  1. Skerfara says:

    ???????? ???????????? ??????!
    in english: Thank you very much.

  2. KrisBelucci says:

    Hi, good post. I have been wondering about this issue,so thanks for posting. I’ll definitely be coming back to your site.

  3. Hi,
    To have gnu screen display current path when at the bash prompt and program name when executing a binary modify your .bashrc to the following(sorry for poor formating):
    ####
    #Set the screen title
    case $TERM in
    screen*)
    # This is the escape sequence ESC k \w ESC \
    #Use path as titel
    SCREENTITLE=’\[\ek\w\e\\\]‘
    #Use program name as titel
    SCREENTITLEPROGRAM=’\[\ek\e\\\]‘
    ;;
    *)
    SCREENTITLE=”
    SCREENTITLEPROGRAM=”
    ;;
    esac

    PS1=”${SCREENTITLEPROGRAM}${SCREENTITLE}${PS1}”

    #####

    Great article. Thanks!

Leave a Reply