I discovered the
screen command recently and it was love at first sight. Before
screen, I was using
nohup to leave commands running in the background
after closing my SSH connection. The rich set of options that the
screen command has,
nohup obsolete for me. In this post I show you my most common use case of
Screen is a full-screen window manager that multiplexes a physical terminal between several processes (typically interactive shells). Each virtual terminal provides the functions of a DEC VT100 terminal and, in addition, several control functions from the ISO 6429 (ECMA 48, ANSI X3.64) and ISO 2022 standards (e.g. insert/delete line and support for multiple character sets). There is a scrollback history buffer for each virtual terminal and a copy-and-paste mechanism that allows moving text regions between windows.
The man page is more than 4000 lines long. And that’s
screen is packed with options.
You can do quite a few things with
- Open an ssh connection, run a job in the background inside a screen and close the connection. You reconnect back later through ssh and open the screen you left open to see how your command is doing.
- Open a screen with a shell in it and share it with other people connected to the same machine through ssh.
- Use it to run several processes in the background using the same SSH connection. I see it as a
replacement of the good old
In this post, I will describe the first use case, which is the most common for me.
In Linux or Windows 10 with WSL, you can use the package manager of your distribution to install it. In Debian based distributions you can use apt:
> sudo apt install screen
In macOS, the best way to install it is by using homebrew:
> brew install screen
screen to run long-running commands
In my current company (Platform161) we run scripts that take several hours to finish. Although we normally use Jenkins to run them, from time to time we need to execute them manually connecting to the machine using ssh.
For those that are not used to work with Linux, if you run a script just by connecting to the machine using ssh and executing it, the script will be run inside your session. If you log out or your internet connection fails, your session will be terminated and your job as well. It’s not enough to run the script in the background since it will be still running in your session.
If you have a backup script that lasts four hours, you don’t want to have it running inside attached to your session. Losing your internet connection 10 seconds before your 3-hout-long job finishes and having to run it again is something extremely infuriating.
We will run the command using
screen instead. Let’s connect through ssh to our machine:
Once we logged in, we run the
[email protected] > screen
and we will be welcomed with a message:
Screen version 4.00.03 (FAU) 23-Oct-06 Copyright (c) 1993-2002 Juergen Weigert, Michael Schroeder Copyright (c) 1987 Oliver Laumann This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program (see the file COPYING); if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Send bugreports, fixes, enhancements, t-shirts, money, beer & pizza to [email protected] [Press Space or Return to end.]
After pressing Space or return,
screen will run a shell. Inside that shell, we execute
our long-running command:
[email protected] > ./long_running_script.sh The script starts to run... progress: 1%...2%...
Let’s say the script takes about 3 hours to complete. Since we are running it inside a
screen session, we can now detach from the screen by pressing
CTRL+A and then
After doing that, we go back to the shell we opened when we logged in using ssh:
Now, our script is not attached to our session but to the screen we created. This way, We don’t depend on the internet connection for our script to run!
…and we can just logout and come back later to check the progress. Before logging out
mymachine.com let’s have a look at the list of screens that are open:
As you can imagine, we can re-attach later to that screen using the identifier
Since this is a command that takes a long time, we will close the ssh connection and check again later.
[email protected] > exit > _
Re-attaching to the screen
After a couple of hours, we want to check the progress of our long-running script. To do that, let’s connect again to our machine using ssh:
Let’s see if our long-running script is stil there. To do that, we get a list of the available screens:
Yes,it’s still there. We re-attach to the screen
2661.pts-0.mycomputer to see how are things going:
[email protected] > screen -r 2661.pts-0.mycomputer
after running this command, the screen will open and we can check the progress
[email protected] > ./long_running_script.sh The script starts to run... progress: ...10%...20%...30%...40%...50%...60%..
We can log out and check again later.
Saving output to a file
We can continue to connect through ssh and check the progress of the script. Eventually, the script
will finish and the
screen -ls command will return that no screens have been found:
[email protected] > screen -ls No Sockets found in /tmp/uscreens/S-alfonso
After the script finishes running, the screen is closed and the output
of our command will be lost. Unfortunately, we don’t know if the command was
successful or not. If I want to save the output of the screen
and keep it after the script ends, we should
-L option. We can also use the
-Logfile option to select where to store the output:
[email protected] > screen -L -Logfile long_running_script_ouput.txt
With these options, once the script finishes, we can look
at the output of the file
long_running_script_ouput.txt to see what happened.
- My colleague Manuel Molina for introducing me to this command that I didn’t know about. Much
more convenient than