32

I have a shared home directory that is automounted via NFS on all the UNIX servers I log in to. I would like to have a single .screenrc that (for example) puts the hostname in the hardstatus line in a different colour to indicate when I am logged on to production versus development; our hostnames are such that this can easily be done through the use of pattern matching.

Is there any way of putting conditional statements into .screenrc? A quick grep of the man page doesn't seem to reveal anything obvious.

EDIT:

To clarify, I already have a custom hard status line; I want to change some of the colouring/fields displayed based on the hostname that screen is invoked on. I already have something like this for my PS1, however I would rather do this in the screen status line as I jump off from these hosts to routers/switches, which don't allow me to do any prompt colourisation. This way, I can have one window for production, and one for development, with the colour of the screen status line telling me which one I am on at a glance.

2
  • Hostname of the machine that screen is running on? Or the host name of that particular screen 'window' is using? Commented May 29, 2009 at 11:35
  • @Kyle: hostname of the machine that screen is running on. See the updated question for a bit more detail. Commented May 29, 2009 at 12:34

5 Answers 5

16

@radius is spot-on with the SCREENRC thing, but it wasn't a very complete answer, so I'll elaborate…

~/.bashrc

# Strip down a FQDN
hostname="$(hostname | sed 's/\..*//')"
# Use the case pattern for server groups
case "$hostname" in
    mario|luigi|toad|peach|koopa*|bowser) export SCREENRC=~/.screenrc_prod;;
    dev*|vm*)  export SCREENRC=~/.screenrc_dev;;
esac
# Use condensed bash "new test*" notation to override for specific servers
# e.g. ~/.screenrc_bowser would get used instead of ~/.screenrc_prod
[[ -f "~/.screenrc_$hostname" ]] && export SCREENRC="~/.screenrc_$hostname"

* Always use new tests!

A word about escape characters

The proper way to include colors in scripts is with tput, not escape characters. Your escape characters are specific to your terminal. The tput command is terminal aware. I wrote this for when I need to get fancy in my scripts:

~/bin/COLORS.sh

GT_RESET=$(   tput sgr0)  # Reset all attributes
GT_BRIGHT=$(  tput bold)  # Set “bright” attribute
GT_DIM=$(     tput dim)   # Set “dim” attribute (normal/non-bright)
GT_ULINE=$(   tput smul)  # Set “underscore” (underlined text) attribute
GT_BLINK=$(   tput blink) # Set “blink” attribute
GT_INVERSE=$( tput rev)   # Set “inverse” attribute
GT_HIDDEN=$(  tput invis) # Set “hidden” attribute

FG_BLACK=$(   tput setaf 0) #foreground to color #0 - black
FG_RED=$(     tput setaf 1) #foreground to color #1 - red
FG_GREEN=$(   tput setaf 2) #foreground to color #2 - green
FG_YELLOW=$(  tput setaf 3) #foreground to color #3 - yellow
FG_BLUE=$(    tput setaf 4) #foreground to color #4 - blue
FG_MAGENTA=$( tput setaf 5) #foreground to color #5 - magenta
FG_CYAN=$(    tput setaf 6) #foreground to color #6 - cyan
FG_WHITE=$(   tput setaf 7) #foreground to color #7 - white

BG_BLACK=$(   tput setab 0) #background to color #0 - black
BG_RED=$(     tput setab 1) #background to color #1 - red
BG_GREEN=$(   tput setab 2) #background to color #2 - green
BG_YELLOW=$(  tput setab 3) #background to color #3 - yellow
BG_BLUE=$(    tput setab 4) #background to color #4 - blue
BG_MAGENTA=$( tput setab 5) #background to color #5 - magenta
BG_CYAN=$(    tput setab 6) #background to color #6 - cyan
BG_WHITE=$(   tput setab 7) #background to color #7 - white

I also made a script to demonstrate the use of tput. You can get it from this gist.

See:
http://www.ibm.com/developerworks/aix/library/au-learningtput/?S_TACT=105AGY06
http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x405.html

2
  • 2
    I found two "inconsistencies". The first is the fact that also for the background setaf is used, although it should be setab (b instead of f) and the second it that using 9 as a default is not working for me, maybe because the tput-version is not standard (either in his case or in mine, I simply don't know and it doesn't really matter much)
    – Shadow
    Commented Aug 14, 2012 at 8:30
  • 1
    @Shadow thanks for catching that. I corrected it. Commented Oct 21, 2013 at 21:12
13

I see two way to do this, the first one is to make a .screenrc file by host.
Like .screenrc_serverA, .screenrc_serverB, ...
In your shell startup script set SCREENRC to something like .screenrc_`hostname`
Of course you can use the source command of screen to include something like .screenrc_default in each custom .screenrc_… files so that they only contains a caption/hardstatus line and not the whole configuration each time.

The second way would be to execute commands like screen -X hardstatus lastline ... (using if tests to execute the command with different value for ... depending of the hostname) in your shell startup script. When you will log on the server, screen -X will do nothing because screen will not yet be launched, but each time you open a new windows in screen the hardstatus will be updated.

Of course the 1st solution is better because the second one will refresh the hardstatus line each time you opened a news windows which is probably useless as the hostname will not have changed.

3
  • When you read ".screenrc_hostname" read ".screenrc_hostname". I got problem to include ` in the post
    – radius
    Commented Jun 30, 2009 at 0:08
  • Nice - I missed the part in the man page about the SCREENRC environment variable being searched first. Commented Jun 30, 2009 at 11:17
  • @radius I was able to add backticks using this suggestion: meta.stackexchange.com/a/70679/167351 Commented Oct 21, 2013 at 21:11
7

Just set it in your .screenrc as the hardstatus variable. As long as you're using a variable like %H for the hostname, it will change to match any hostname you work on it.

hardstatus alwayslastline "%{rk}%H %{gk}%c %{yk}%M%d %{wk}%?%-Lw%?%{bw}%n*%f %t%?(%u)%?%{wk}%?%+Lw%?"

Will give you a status line at the bottom that looks like

screen hardstatus example

hostname is red on black, time is green on black, date is yellow on black. window marked with * is the current window, shown in blue text on white background. window marked with - is the previously active window, shown white text on black. window 1, above, is neither current, or previous, and would be shown in white on black. the other possibilities would show you other users attached to windows, white on black, and be marked by +.

having the time display also helps with keep alives if you ssh to remote servers to run screen, as the time changing every minute will keep your session alive, even if the shell is idle on the remote side.

2
  • That doesn't allow me to conditionally format the hostname based on its structure (e.g. any hostname ending in '-dev' in blue, any hostname ending in '-prod' in red.) Commented Sep 27, 2011 at 17:54
  • ah. if only screenrc if-statements supported regex. Commented Sep 27, 2011 at 20:47
4

You can colour the status line from within a backtick script by printing \005{..r} or similar (r for red etc. just like within the .screenrc itself), so you could either hash the hostname to arrive at a number, or just have a bunch of conditional statements to set the colour. As an example, here's a script to change the colour and print the hostname for use within screen:

#!/bin/bash
Red="\005{..r}"
Yellow="\005{..y}"
Green="\005{..g}"
Blue="\005{..b}"
Magenta="\005{..m}"
Cyan="\005{..c}"
White="\005{..w}"

case "$HOSTNAME" in
   lubuntu-eee)
      echo -e "$Magenta$HOSTNAME"
      ;;
   ubuntu-pc)
      echo -e "$Magenta$HOSTNAME"
      ;;
   *)
      echo -e "$Green$HOSTNAME"
esac

You then add an entry for this script to the .screenrc and reference it within the hardstatus or the caption as %4`:

backtick 4 3600 3600 /usr/local/bin/screen_hostname
caption always "%{.kc}%D %d.%m.%Y %=%{.kg} %4` %{.kc}%0c"

This assumes the hostname is unlikely to change, hence the timeout and validity of 1 hour (3600 seconds); the bits surrounding the call to the backtick itself just put the date at the beginning of the line and the time after the hostname.

You can even use this mechanism to colour the output of a script depending on the value of the battery charge level, system load or temperature, assuming you have access to the relevant values from a shell script.

1
  • +1 for mentioning the screen escape \005 - that way the whole conditional formatting can be put into a much more readable shell script instead of those already hard-to-parse caption resp. hardstatus screen directives.
    – ckujau
    Commented Aug 14, 2019 at 6:16
2

If you want to avoid lots of scripting you could try this:

backtick 5 99999 99999 grep prod /etc/hostname
caption always "%?%{.R.}%5`%:%H%?"

grep will only print the hostname if it matches "prod", so you can plug that in to a backtick and the %? construct. Viola!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .