GNU screen - Have a terminal in your terminal !

How to bind a function to a key within screen ?

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
  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 !!!

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 CDK
stuff "cd CDK/Doc; clear^M"

screen -t works
stuff "cd works; clear^M"

screen -t bash

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

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

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...

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 :

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'

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

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

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 the start (or the end) of the chunk to select, then
  3. move the cursor to the other end of the chunk to select, then again. The status line should say :
    Copied 42 characters into buffer
    Doesn't seem to work when using a status line...
  4. Several solutions to retrieve the copied text from screen's buffer :
    1. you can output it :
      • directly into the current shell window. This can be dangerous if the copied text contains commands and carriage returns. Use with GREAT CARE !
      • into a text editor : vi, nano, emacs, ... Looks safer .
      To proceed, paste the text from screen's buffer : CTRL-a, ].
      Doesn't work (anymore?)... Maybe only one tiny detail is missing... See the other solution below instead
    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
  5. Enjoy !

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.

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

screen

Usage :

The screen program creates multiple processes instead of multiple Unix login sessions, which means that it is resource-efficient. Using the detach feature, you can save screen processes when logging out and resume where you left off, saving the trouble of restarting them.
screen can be configured and customized in ~/.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
-ls -list show all available screen sessions and their PID
-d detach a screen from outside the session. This is useful when the SSH session was killed by a network problem (details).
-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.

Hotkey (see all) 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
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, 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. (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

h, j, k, l
-, +
/something, ?something
In copy mode (Vi-like) :
left, down, up, righ arrows
1 line up, 1 line down
Search something forward, backward

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