Scripting screen for fun and profit... :)
This article is written in english and rather long. First of all to improve my written english. But more importantly to get a bigger audience for this article. :-) I hope my english is not that bad.
People reading my blog know that I am a console-cowboy, meaning I mainly use
console tools to do my work. As every cool console-cowboy naturally I use
screen to manage my applications and displays.
I assume people reading this article already know about
screen and its
benefits and just want to learn how to get more out of it. But for all those
people who don’t know about screen or why to use it, here are some random
screen detaching (safenet if you have a flaky network connection)
saving screen real estate
no need to use the mouse (everything can be done with the keyboard)
using the scrollback buffer you can view and search in the output of commands
using detached screens you can put interactive console tools into the background, like a daemon
many others I can’t remember just now
Gnu screen is a very powerful tool and has a lot of features which are sometimes not that easy to grasp. But investing some time into learning it can speed up your workflow a lot!
An introduction to
screen can be found here:
Basics of screen scripting
OK. Enough chit chat. Lets get down to business. Most of the time you will use
screen interactively. You want another screen windows, you press the buttons.
But maybe unknown to some,
screen is in some sort scriptable. It
unfortunately is not straightforward and the very good manual gives only hidden
hints. But if you know the edges it’s quite helpful.
The first and basic parameter you need to know is
-X. With this parameter you
can send screen commands to any screen session (for a list of screen commands
take a look at the very fine man page for screen). By default it uses the
screen session you are currently attached to. So just to test this, start
screen, create a second window pressing
C-a c. Now enter the following line
at the shell prompt:
$ screen -X next
Wow. You just left the current window and went to the next window. This is the
same as pressing
C-a n or
C-a :next<CR>. Impressive, isn’t it? :)
Where could this be used. Consider a program which needs a very long time to
complete. You could start it inside a
screen in the following way:
$ longrunningapp.sh; screen -X select <thiswindownumber>
You can get the windownumber by pressing
C-a w. It’s the number right
in front of the name of the screen which is marked by the star. If your windows
have distinct names you can also use the name as parameter for the
This line starts the application. After the application finishes the screen session focuses on the applications window, which means you will be automatically brought to that window. You don’t lose time looking and looking whether the application already finished. In the meantime you can continue work in another window.
screen -X -p
We just talked about different windows and their names/numbers. Consider the
stuff. It is used to send keystrokes to a window. By default
the current window is used as the target. But this command is not very helpful
if used interactively like
$ screen -X stuff hello
This way you can write notes to yourself. But if you add the parameter
-p to this line you can send those commands to another window in the
same screen session. Now this is helpful. You can remote control applications
in windows this way. Consider the following example:
Create a screen-window and start e.g.
w3m in it to show a webpage which
changes over time (w3m is a console web browser
like lynx or
links). This could be
a webpage showing usage statistics or stock information on the net or whatever.
For this example we will use a page which shows the current weather for munich:
$ w3m http://www.meteo24.de/wetter/49X7464.html
This will output the current temperature etc. for munich. Unfortunately this display is not updated automatically. You manually have to reload the page. Let’s see how screen can help us.
Give the window a distinct name or just use the number of the screen window.
To rename the current window to another name press
C-a :title watchit. The
current screen window now has the name "watchit". Enter
C-a w to check this.
Now comes the interesting part. Go to another window in your screen session.
To reload the website in w3m you have to enter
Shift-r). So using the
following line we periodically send
R to the w3m-window which then reloads
the website and updates the display.
$ while true; do screen -p watchit -X stuff R; sleep 5m; done
sleep-command is used to reload the webpage only once every 5 minutes.
You can enter nearly any value here. See
man sleep for more information about
As you can see we now can remote control
w3m. This might be a very simple
example for remote controlling. With some experimentation you will certainly
find more uses for this technique. Remember that
w3m was just an example. We
really only sent keystrokes to the other window. So any console tool can in
principle be remote controlled using
screen -X -p -S
Now lets take another step and remote control windows in other screen sessions.
Remember that screen can be started on several terminals which creates several
screen instances on your computer. You can see those screen-instances using
$ screen -ls There is a screen on: 1840.pts-0.work (Attached) 6027.pts-5.work (Attached) 2 Sockets in /var/run/screen/S-gerhard.
As with windows in screen sessions, several screen instances (called sessions)
can be identified by their number and their name. You can give a new screen
session another name than the default one (which is the name of the tty it is
started in) by adding the parameter
-S at the command line (you have to be
outside screen to start a new session!).
$ screen -S mysession
If you now run
screen -ls you will see something like this:
$ screen -ls There are screens on: 1840.pts-0.work (Attached) 6027.pts-5.work (Attached) 6203.mysession (Attached) 3 Sockets in /var/run/screen/S-gerhard.
Other information in this output is whether the session is currently attached (meaning if it is currently shown on any terminal) or detached. Detached screen sessions are still running like attached screen sessions, but are not displayed anywhere.
Now to send a screen command to a certain screen session you can use:
$ screen -S mysession -X stuff hello
Try it and you will find the word hello in the currently open window in the other screen session.
Together with the
-p parameter we now are able to send any screen command to
any screen session (which is owned by yourself. screen does have some
multiuser capabilities. But to describe them I will have to do another tutorial
someday). The screen sessions have to run on the same computer though!
To get the current identifier of the screen you are currently in, you can read
$STY. This way you have an identifier from inside
$ echo $STY 1840.pts-0.work
This environment-variable can also be used to check if your scripts is
currently running inside an screen session. Be aware that if you change the
name of the screen session via
C-a :sessionname myname only
screen -ls will
show the correct name. $STY still will show the name the session had on
A thing to look out for
On thing to keep in mind while scripting screen is to be aware, that commands send to screen via the screen-command might not be finished when the commands returns. They might not even have worked correctly. The commands are put into a queue where they are execute when possible. So you don’t know wether a command was received, when it will be executed and if the execution was successful. The screen -X command works asynchronous. Take a look at the window-content-example below which demonstrates this point.
Examples for simple screen scripting
The following are simple examples on how to use screen scripting to do some things. I am expecting you to use bash as your shell. You might have to convert the examples to other shell environments if you are not using bash.
Checking if you are inside a screen session
$ if [ -n "$STY" ]; then echo 'We are inside screen'; fi
Getting the contents of a window
hardcopy-command you can send the content of a screen window to a
file for further observation. This way you e.g. could check in what state a
remotely controlled application currently is. Be aware, that on exiting the
screen-command doesn’t mean, the file is created! Unfortunately you have to
wait for it to be created. Normally if you just sleep for some time after
issuing the command should be enough. But you could also check for the file in
a tight loop.
$ screen -S screenname -p windowname -X hardcopy /tmp/filename; sleep 1s; cat /tmp/filename
You can also get the whole content of the scrollback buffer if you add
The output in the filename also contains the screen status bar, if turned on. This can be used to check which window the screen session was in when the command hit it. Naturally you have to output the window name in the status bar to do this. :)
Running a screen window dia-show
Suppose you have several running console applications which output different changing data. As a screen lover you put them in several windows. If you want to see the output every now and then, you manually have to switch to all the windows and take a look (obviously you also could split the screen, but thats not always possible).
With the following line you can create a simple dia show effect, where every windows is shown for a small amount of time. You only need to now the sessionname of the screen session where the applications are running in. This way your precious data is constantly presented to you.
$ while true; do screen -S sessionname -X next; sleep 10s; done
A real script using screen is my screengraph-utility. It is available from this
very website with full source code. Effectively it just uses
gather the data from the designated screen window and then outputs the found
data using gnuplot.
You now know how to send noninteractively commands to any screen windows running on your computer. With this knowledge you are able to automate your console tools, even if they are fully interactive. If you create interesting scripts using this technique please tell me. If there are enough ideas I might post another blog entry with those ideas. Just send them to firstname.lastname@example.org
I hope this article was of some help to anyone. Please post comments if you have annotations or if you find something that is wrong.
Example with long running example was wrong (2012-08-22).