Using “screen” on Linux

The screen utility is available on most Linux systems, including Fedora, CentOS and RedHat.

The history of screen is that it was an essential tool in the old days of dial-up access to servers, terminal sessions running under screen could survive a session disconnection; the user could just log back onto the server and re-attach to the screen session(s) without losing any work.

These days it is still extremely useful due to its ability to allow users to manually disconnect from screen sessions and re-attach to them at a later time. Very useful if you want lots of tasks happening but do not want to open lots of windows.

While there are terminal emulators out there now that allow split screen windowing the main advantage of screen over other tools is the ability of screen sessions to survive in detached mode reguardless of what terrible occurences occur that may kill your terminal/ssh session.

One specific and very valid use is when you perform yum/dnf updates on a remote server via ssh. I am sure we have all hit the situation where an update causes a network reconfiguration (network drops) killing the update midway through as the ssh session dies. If on the remote server ssh session you simply screen bash and perform the update within the screen session while the network will still drop and kill the ssh session when the network comes back you can simply ssh back onto the remote server and use screen -r to reconnect to the screen session which will still be performing the update quite happily.

This is because the default behaviour of screen is that autodetach currently defaults to on so it handles an attached client suddenly dying quite happily, while that can be changed in /etc/screenrc just do not change it.

But I personally find screen most useful in application startup scripts.

There are still applications in the wild today that need to be started from a terminal, either for logging or so that command input can be provided to them, some of these provide startup scripts that may redirect output to a log file and input from a pipe file to work around the issue, when it would be far simpler to simply start the application in a screen session.

It should be noted that applications that provide scripts that do all that messy redirection do so for portability, as not all *nix operating systems provide screen, for example AIX has a screen command that unfortunately does something completely different so screen cannot be used on that OS and the vendor might like their application to run on AIX.

However all Linux systems provide screen, and the many features it can provide in startup scripts for applications that require terminals seem to be overlooked. What screen provides for scripts is

An important thing to note within this post is that where I use CTRL-a I am refering to the Control-Key and ‘a’ key combination, do not type the ‘-‘ which is just in the post as most manuals refer to key combinations that way so familiar to most readers.

  • screen sessions can be ‘named’, allowing them to be easily identified and re-attached to
  • a ‘real’ terminal session, as far as the application is concerned it has been started in an interactive terminal
  • the screen session can be detached (become a daemon/background task) at the time it is created, it does not have to be manually detached, and it will continue to be an active terminal for the application
  • and of course at any time you can manually re-attach to any of the screen sessions for a full terminal experience in issuing commands and viewing output messages
  • you can also kill screen sessions by name should you not want to bother reconnecting to them to stop them, usefull for shutdown scripts
  • it cannot despite what the ‘man page’ says accept commands passed to a named screen session via the -X -S flags, at least I have never been able to get that to work

Also incredibly useful uses for screen outside of scripts are

  • At any time you can display a list of active screen sessions for the userid you are logged on as using screen -ls making it easy to re-attach to sessions
  • screen sessions survive any fatal error that affects the terminal/ssh session that started them, so sensitive/critical commands you do not want interrupted should be run in screen sessions
  • while the root user cannot list another users screen sessions root can connect to another users screen session with screen -r sessionowner/[pid.tty.host] if the user has manually set the screen session to be multi-user mode (not the default) and provided the session name. This is very useful for debugging user issues as exactly what is being seen by the user can be seen by the additional root connection to that screen session, which can also issue commands as the user owning the screen session. However to allow root to connect the user would need to within the screen session type CTRL-a:multiuser on followed by CTRL-a:acladd root to make the session multi-user and allow root to connect so not a security risk as the user is in full control of access
  • A single screen session can with “crtl-a-c” create new windows that are also full screen sessions, that can in the simplest form be tabbed bewteen using “ctrl-a-[space]”, this is usefull for those occasions where the only connection to the server may be the console for troubleshooting, you can just ‘tab’ betwen windows using “ctrl-a-[space]” to switch between a window constantly tailing a log file and a window issung commands for example; where with a normal console session only one thing at a time can be done

Example 1: multiple screen sessions

A simple example however of using screen in a script is shown below. The “-t” sets a title for the session window and the “-S” is the name of the session. The “-d -m” flags together indicates the session is to run detached. The last argument is simply the program the screen session is to run.


#!/bin/bash
screen -t bash_shell1 -S bash_shell1 -d -m bash
screen -t bash_shell2 -S bash_shell2 -d -m top

At this point when the script finished running screen -ls would show you have two detached sessions, you could re-attach to the first session with “screen -r bash_shell1” and find a normal shell session, use ctrl-a-d to detach, re-attach to the second session with “screen -r bash_shell2” and be connected to a session with ‘top’ running quite happily.

It should be noted that when a program started by screen ends the screen session ends, for example using ‘q’ to exit top or ‘exit’ to leave the bash shell running under screen will end the screen session you are connected to. The correct way to detach, if you intend to leave the session running, is to use ctrl-a-d. Obviously screen is most usefull for interactive use if you start bash in each one, but for startup scripts you can run any command that needs a terminal in immediate detached mode.

screen is obviously most useful in startup scripts where you have applications that need a real terminal(s).
I personally found the benefits of screen in writing a script to start turnkey3 under hercules that needed a terminal for hercules, a telnet session for the hardcopy device, and a couple of 3270 sessions for consoles that I used c3270 with scriptports to pipe the console commands into to start the system; on a headless server so doing so manually was a pain so scripting was essential and only screen (in this case combined with being able to issue console commands via scriptports to c3270) provides the functions needed.

Example 2: one screen session, multiple windows

At a terminal prompt simply type “screen” to start a screen session running the default shell. Within that session use crtl-a-c (control a c) to start another window within that screen session.
In the second session that you just created run “top”.
Use ctrl-a-[space] (control a spacebar) to switch to the first window.
“screen -ls” will show only one screen session running, that you are attached to.
Use ctrl-a-[space] (control a spacebar) to switch back to the second session and use “q” to quit top, then “exit” to close that window.
You will be back at the first window. “screen -ls” will show a screen session attached to of course, use ‘exit” to close the last window and end the screen session.

You can use ctrl-a-c up to nine times as needed within a screen session to create as many windows [0-9] as you need, you can switch to them by number with “ctrl-a-N” where N is the number of the window. As you can see being able to run multiple windows via a console session which would normally only have the one command prompt is invaluable for troubleshooting; as long as when you are done you remember to exit all screen windows.

Example 3: Sharing a screen session

It is possible to have multiple users attached to a screen session, although this is fully under the control of the user that starts the screen session. The obvious benefit of this is that if a user is having difficulty doing something in a terminal session such as starting an application that keeps failing a support person of sysadmin can share their screen session to see exactly what they are doing, and by default also be able issue corrective commands themselves.

To achieve this a user starts a screen session as normal and makes a note of the session id.

[mark@phoenix posts]$ screen bash
[mark@phoenix posts]$ screen -ls
There is a screen on:
        17349.pts-3.phoenix     (Attached)
1 Socket in /run/screen/S-mark.

At this point if the screen id (17349.pts-3.phoenix) was provided to an admin then using the ‘root’ userid the command ‘screen -r username/17349.pts-3.phoenix’ would produce an error that the session is not shared but private.

[root@phoenix ~]# screen -r mark/17349.pts-3.phoenix
There is a screen on:
	17349.pts-3.phoenix	(Private)
There is no screen to be attached matching 17349.pts-3.phoenix.

It is entirely up to the user to permit the session to be shared, which they can do from within their screen session with the key combination and command CTRL-a:multiuser on, which changes the ‘root’ users connection error message to be

[root@phoenix ~]# screen -r mark/17349.pts-3.phoenix
Access to session denied.

This is because the user owning the screen session must explicitly define who can access the screen session, which they then do in their screen session with the key combination and command of CTRL-a:acladd root, after which the ‘root’ user can connect to the users screen session.

By default an added ACL gives the added user full access to the screen session, there are options to limit that access such as to read only if needed you can find in the ‘man screen’ documentation.

One important thing to note is that if any of the connected users with write access to the session then type ‘exit’ into the screen session the session will end, users need to use the normal CTRL-ad combination to detach from the session if they want to leave it running.

Also note that a ‘screen -ls’ will show the screen session is in multiuser mode but will not show all the users attached to it.

[mark@phoenix posts]$ screen -ls
There is a screen on:
        17349.pts-3.phoenix     (Multi, attached)
1 Socket in /run/screen/S-mark.

You will have noticed that in my example I used the ‘root’ user as the user to connect to another users screen session, it is not required to use the root user. Any user that has read/write access to the screen sessions socket file can be permitted to attach to that users screen session, however it is more practical to use the ‘root’ user as having to ask the user to chmod their socket file could prove difficult as the ‘man page’ for screen lists many locations the socket file could be created in, and in Fedora30 it is not in any of those locations making it impossible. So on Fedora30 as ‘screen’ knows where to find the socket file and ‘root’ of course has access to it the root user needs to be used.

Issues with using screen in startup scripts on systems that use systemd

Screen was extremely useful in the old SYSV /etc/init.d startup script days, where a startup script would start a few processes and the startup script itself then exit, leaving the processes it started running. systemd does things differently.

If your startup script is still managed by chkconfig and in the old SYSV init.d filesystem directories at system boot time systemd servers (Fedora 30 certainly) will at boot time map them to systemd services. For example /etc/rc.d/init.d/my_script enabled by chkconfig can be displayed with systemctl status my_script.service, and even though it has run it will show as stopped and no processes started by it will be running anymore.

The reason for that is systemd by default expects the entire application service to be encapsulated by default and when the main service script stops running systemd will also stop all processes started by that main service script; by design to ensure a stopped service is cleaned up. So previously used init.d scripts designed to start things and exit cannot be used by systemd without modification, as systemd startup commands cannot be permitted to exit.

There are ways around that which I will cover with a later post on systemd, as I don’t wish this post on screen to become a systemd tutorial.

About mark

At work, been working on Tandems for around 30yrs (programming + sysadmin), plus AIX and Solaris sysadmin also thrown in during the last 20yrs; also about 5yrs on MVS (mainly operations and automation but also smp/e work). At home I have been using linux for decades. Programming background is commercially in TAL/COBOL/SCOBOL/C(Tandem); 370 assembler(MVS); C, perl and shell scripting in *nix; and Microsoft Macro Assembler(windows).
This entry was posted in Unix. Bookmark the permalink.