GNU screen - Have a terminal in your terminal !

mail

How to change the number of a GNU screen window (i.e. move it) ?

  1. go to the window you'd like to re-number / move
  2. type :
    Ctrl-a :number n
    with n : new number of the current window
    • if there is already a window n, the current window and the window n are swapped
    • otherwise, the current window becomes the window n
    If you mistype / forget the :, and actually start typing Ctrl-a n, you'll switch to the next window .
mail

How to free the Ctrl-a key sequence for Emacs ?

As seen in the GNU Screen hotkeys article, hotkeys are prefixed with a Ctrl-a sequence, which is not ok for Emacs users because Ctrl-a is a very common shortcut. This prefix can be changed : but this is not (yet ) completely clear to me.

What the docs say :

  • Ctrl- key sequences are written C- in the manual, but they actually have to be specified using the caret notation : ^. For example : Ctrl-a becomes ^A
  • the escape directive takes 2 concatenated arguments : Each of these arguments can be :
    • a single character
    • a two-character sequence of the form ^x (Ctrl-x)
    • a backslash followed by an octal number (specifying the ASCII code of the character)
    • a backslash followed by a second character, such as \^ or \\
    Defaults to ^Aa, but `` is recommended by one of the authors.
  • the command character (aka the "command command" or simply the "escape")
  • the meta command

Back to our Emacs question :

On the second row, next to the 1 key, my keyboard has a ² key that I never use (depending on the context, it "writes" either œ or ²). Let's use it as the "command command" by adding to ~/.screenrc :
# free the escape sequence ('Ctrl-a') by setting it to a suggested default I never use
escape ``
# set my own sequence
bindkey "²" command
mail

How to use variables in .screnrc ?

  1. declare a variable :
    setenv variableName variableValue
  2. use it as any shell variable :
    cd "$variableName"
As said in the documentation : The environment is inherited by all subsequently forked shells.
This means that variables declared this way :
  • will not exist in pre-populated Screen windows
  • will exist in any Screen windows opened afterwards with Ctrl-a, c. You may :
    • list it :
      env | grep variableName
    • use it normally :
      echo "$variableName"

So you'd better choose variable names that won't collide with other usages. So far, I prefix such variables with gnuScreenDotscreenrc_.

mail

GNU Screen hotkeys

Hotkey Usage
Ctrl-a, A Annotate : set the Screen window name
Ctrl-a, c create a new window inside a Screen session
Ctrl-a, d detach from the Screen session and all its windows (details)
Ctrl-a, k kill : leave the current window (same as exit). NB : when all windows are killed, Screen dies also
Ctrl-a, M Toggle Monitoring of activity in the current window
Ctrl-a, n Switch to the next window
Ctrl-a, Q Maximize current window and leave split screen mode (details)
Ctrl-a, q exit "command buffer"
Ctrl-a, S split the current window with an horizontal line
Ctrl-a, X delete the current region when in split mode
Ctrl-a, n select Screen window number n (get Screen window numbers)
Ctrl-a, " list windows of current Screen session : number + name + flags
Ctrl-a, | split the current window with a vertical line
Ctrl-a, ESC
Ctrl-a, [
Enter copy mode allowing to scroll beyond the top of the display output. Exit with ESC or q. (source)
Ctrl-a, TAB Switches windows once in split screen mode.
Ctrl-a, : Enter console mode. This allows to type commands to alter the current session on-the-fly without editing ~/.screenrc
In copy mode (Vi-like)
  • h, j, k, l
  • -, +
  • /needle, ?needle
  • during search : n, N
  • left, down, up, right arrows
  • move cursor 1 line up, 1 line down
  • search needle forward, backward
  • repeat search in same direction, opposite direction
mail

Screen : how to bind a function to a key ?

The very purpose of this hack is to quickly insert a string into a terminal window without having to type it repeatedly. If this string is a list of commands you want to run again and again, you should considering making a shell function instead.

I have some repetitive commands to run manually and I want to make things easier : it would be great if, when I press F3, this is a long string and I'm a lazy guy could be added at the current cursor position in a terminal (Screen window, actually).
To do so :

  1. append to ~/.screenrc :
    bindkey -k k3 stuff "this is a long command and I'm a lazy guy"
    • kn (1≤n≤9) matches the Fn keys
    • Fn (0≤n≤2) matches the F(10+n) keys
    source
  2. To simulate the final key press, just add ^M after the command :
    bindkey -k k4 stuff "ls -1^M"
  3. start a new screen to use it
  4. enjoy !!!
mail

Is it possible to pre-populate Screen windows ?

Sure it is possible !
To do so, you'll need some extra commands into ~/.screenrc :
screen -t screenWindowName
create a new window named screenWindowName
select screenWindowNumber
Equivalent to Ctrl-a, screenWindowNumber
stuff string
Put string into the input buffer of the current window, as if it were typed from the keyboard. If string is a shell command, you'll have to simulate the final keypress by sending the corresponding key code : \015

Append to ~/.screenrc :

screen -t window_1
stuff "cd path/to/some/directory; clear^M"

screen -t window_2
stuff "cd some/other/directory; clear^M"

screen -t window_3

select 0	show window 0 (i.e. the one named window_1)
mail

How to get / set the scrollback value ?

Get :

None of these solutions actually work because of the "hardstatus" line :
  • Ctrl-a i
  • Enter copy mode, the bottom line should display :
    Copy mode - Column 71 Line 25(+3000) (80,25)
    Here, scrollback is set to 3000 lines.

Set :

Temporary :
in console mode : scrollback 10000
Permanent :
Add to ~/.screenrc :
defscrollback 10000
mail

How to change the Screen window settings : color, background color ?

Altering Screen window settings can be done by sending the appropriate ANSI codes with the right value. For instance, it is fairly easy to set the Screen window title. Similar changes can be made with the font + background colors.

First things first, to change the font and background color of an XTERM via Bash, just run :
echo -e '\e]11;darkblue\a\e]10;gray\a'
To change the screen window title, we had to :
printf '\ek%s\e\\' "new window title"
This is all about printing the right control sequence in the format :
printf '[ESCAPE_SEQUENCE][SOME_VALUE][CLOSING_CONTROL_SEQUENCE]
Browsing these control sequences shows :
ESC k		Title Definition String

ESC P	(A)	Device Control String
		Outputs a string directly to the host
		terminal without interpretation.
So let's mix things up and see what happens :
  • echo -e '\eP\e]11;darkblue\a\e]10;yellow\a\e\\'
  • echo -e '\eP\e]11;black\a\e]10;white\a\e\\'
format : echo -e '\eP\e]11;backgroundColor\a\e]10;textColor\a\e\\'
This works fine, but also alters ALL windows (existing + future ones) . Maybe I'll find a workaround...
mail

How to detect whether the current shell is executed within a Screen ?

Easy solution (source) :

$STY has a value in Screen, and is empty otherwise.

This is $STY, not $TTY !

Not-so-easy-but-interesting-though solution :

When running any shell command, processes are nested like this :
  • either a terminal or Screen
    • the shell itself : /bin/bash
      • the shell command. The PID of this process is stored in $$
So we just have to run a command returning the name of its grandfather :
mail

How to get / set the Screen window title from the shell ?

Read the current window title :

windowTitle=$(screen -Q title); echo "$windowTitle"

There's a little glitch with the screen -Q command : it displays its result in the window "notification area" (bottom line) for a few seconds, which freezes the shell during that time. This delay is controlled by the msgwait directive, which can be reset by adding to ~/.screenrc :

msgwait 0

Set the window title (source) :

You just have to print the new title within the right escape sequence :
printf '\ek%s\e\\' 'new window title'
mail

How to work in split-screen mode ?

Once in a Screen session :
  1. Split the window with an horizontal or vertical line
  2. Switch to the next sub-window
  3. Once in the new sub-window, create a new Screen window
  4. Have fun !
  5. Leave the split-screen mode
mail

What if I can not completely detach a session then re-attach it ?

It sometimes happen to be uncleanly disconnected from a Screen session (computer hangs, network problem, ...). In such case, the session is not always automatically detached, and screen -ls outputs :
There is a screen on:
PID.sessionName	(Attached)
1 Socket in /var/run/screen/userName.
So, running screen -d sessionName should do the trick and let the session be resumed with screen -r sessionName. However, sometimes this doesn't work as expected (for unknown reasons so far), since after trying to detach the session, screen -ls still displays it as attached.
The solution is then to detach+reattach the session :

screen -d -r sessionName

mail

How to copy text from a Screen session ?

This procedure is pointless for small chunks of text that fit the display : just select/copy text with the mouse as usual

  1. enter copy mode
  2. move the cursor to one end of the chunk to select, then
  3. move the cursor to the other end of the chunk to select, then again.
  4. unless you're using a solid status line, it should display :
    Copied 42 characters into buffer
  5. there are several solutions to retrieve the copied text from screen's buffer :
    1. paste it :
      • directly into the current shell window.
        This can be dangerous :
        • with long chunks of text
        • if the copied text contains commands and carriage returns
      • into a text editor : vi, nano, Emacs, This is much safer than pasting directly into the shell (but I can't remember how to do it with Emacs ).
      To proceed, paste the text from screen's buffer : Ctrl-a, ].
    2. Use heredocs, without even leaving your terminal window :
      1. just type :
         cat << EOF > path/to/someFile
      2. at the prompt : paste the copied text with Ctrl-a, ]
      3. type the heredoc stop token : EOF
      4. the text is in path/to/someFile
    3. alternate (Emacs + process substitution + heredocs)-based solution : "pass" text as an argument while opening your editor :
      1. type (source) :
         emacs --insert <(cat <<EOF
      2. at the prompt : paste the copied text with Ctrl-a, ]
      3. type the heredoc stop token : EOF
      4. type the closing ) +
      5. Emacs will open showing the pasted text
  6. Enjoy !
mail

Cannot open your terminal '/dev/pts/11' - please check.

Situation

You may get this error when : logged as root + su - bob + screen -x session_belonging_to_bob.

Solution

  1. chmod o+rw /dev/pts/11
  2. screen -x sessionID

Alternate solution

Or (clean way), consider Screen's multiuser mode.
mail

How to share a Screen session ?

In this scenario, Kevin and Stuart are logged on an host using the same local account (for 2 distinct user accounts, read this). This scenario is equivalent to opening 2 SSH sessions simultaneously on a single host.
  1. Kevin logs on hostScreen
  2. Kevin starts a new Screen session : screen
  3. Stuart logs on hostScreen
  4. Stuart can look for existing Screen sessions (and their PID) : screen -list
  5. Stuart attaches to the session in "sharing" mode : screen -x PID
mail

screen

Usage

Screen : Screen can be configured in ~/.screenrc (default configuration : /etc/screenrc). Here's a minimal configuration :
autodetach on
startup_message off
hardstatus alwayslastline "%{kb}%{c}[%{w}%D %d/%m/%Y %c:%s%{c}] %{w}%-w%{rk}%n %t%{wb}%+w %=%{c}[%{W}%H %l%{c}]"

bindkey -k k6 prev
bindkey -k k7 next
This binds F6 to the previous window, and F7 to the next one. You _may_ also bind a function to a key in Bash.

Flags

Flag Usage
screen
screen -S sessionName
start a new anonymous / named Screen session
-c configFile override default configuration file ($HOME/.screenrc) with configFile
To ignore the default configuration file : screen -c /dev/null
-d detach a Screen from outside the session. This is useful when the SSH session was killed by a network problem (details).
It is also possible to detach from inside the session.
-ls -list show all available Screen sessions and their PID
-r
-r PID
-r sessionName
resume the Screen session having the specified PID. The PID can be omitted when there is only 1 Screen session
-x
-x PID
Attach to a not detached Screen session. (Multi display mode, allowing several users (or several incoming connections) to share a Screen). The PID can be omitted when there is only 1 Screen session.

Example

How to list all the Screen sessions :

find /var/run/screen -type p
(works better as root )

Screen and PuTTY :

You may find situations when as soon as you scroll up in a PuTTY terminal running a Screen session, that the display goes back to the bottom of the window (i.e. cursor position) almost instantly (after ~1s). To disable this behavior, edit the PuTTY session settings :
  1. Open the Settings | Window page
  2. untick Reset scrollback on display activity