GNU screen is a useful tool, it has been mentioned in multiple earlier articles as a good way to keep a program running after you log out of a server.

Screen runs commands in sessions. Each session can have multiple screens in which commands are run, which can be a more useful interface to multiprocessing than running jobs in the background.

A screen session can be connected to by multiple terminals, and can be detached from entirely, so there's no user reading the command's output.

Creating a session

The simplest use of screen is to simply enter screen at which point it creates a new session, running your shell.

Commands other than the default of your shell can be executed too. You can run screen tail -f /var/log/foo.log to watch the logged output of a command.

You can specify the name of the session with the -S argument, which can be used later to re-join or kill a session by name.

Entering commands

Screen has many default key-bindings for running commands. These are mostly prefixed by the escape key. This defaults to ^A (read as holding Ctrl an pressing the a key).

^A is commonly used by emacs users to move the cursor to the beginning of the line. It is possible to re-bind to a different key by putting escape $KEY in your ~/.screenrc.

escape ^Bb will make screen use ^B for its escape character, rather than ^A.

Commands that had not been bound can be entered by entering the ^A: command (hold Ctrl, press a, then press :). This will open a command line interpreter, where you can enter other commands.

Opening a new screen in your session

The screen command will open a new screen in the same session. The keyboard shortcut for this is to enter ^Ac, which opens a new screen and runs a shell in it.

To run a specific command in your new screen, just like how we create the initial screen session, just in the screen command line, rather than your shell's command line.

For example, entering screen tail -f /var/log/foo.log in the command line opened by pressing ^A:, will open a new screen and read the output of foo.log into it, which can be used to monitor the logs of a command being run in another screen.

Switching screens

^Aa will switch between your current screen and your previous screen.

Your open screens are listed in the caption at the bottom of the screen. Pressing ^A$NUMBER will switch to that screen, so ^A1 will switch to the first screen.

^A" will open a menu of screens to switch to, including what command is running in that screen, which is useful if the information in the caption bar isn't sufficient.

The command to switch screens is called select, so running select 1 in screen's command line will switch to screen 1.

Splitting screens

Using screen to manage multiple commands is already an improvement over bash's job control.

  1. The caption bar shows you which commands are running
  2. You don't need to background a command to have multiple running
  3. The output from multiple commands doesn't get interleaved into an incomprehensible mess, since the output is separated by screen.

However, we currently can only see the output of one command at a time, so we can't use our earlier example of looking at the logged output of the foo command, while running other commands.

To handle this, screen allows you to split your view into multiple windows.. ^As produces a horizontal split, so you can have one window at the top, and a different below it.

^A| creates a vertical split, so you can have a different window on the left and the right.

Various windows can be cycled between with the ^A<TAB> key.

^AX will remove the current split, and ^AQ will remove all windows except the one which currently has focus.

Closing screens in your session

When the primary process of a screen terminates, the associated screen will close, so if you enter exit on your shell, the screen will close.

If a screen is stubbornly refusing to exit, you can run ^Ak to kill the current screen.

Closing a session

When all commands run in a screen session exit, the session is closed.

If a command is not easily closed or you do not care for cleanly closing it, then you can press the ^A\ shortcut to kill everything, or entering the quit on the screen command line.

Detaching from a session

A screen session can be left running without any user being connected to it. This can be accomplished by creating one as before, and pressing ^AD to detach yourself from it.

A screen can be started in detached mode by starting it as screen -d -m.

Joining an existing session

screen -x will join an existing session, even if there is currently a user already attached. This allow multiple users on the same screen session, but can behave strangely if each user has a different terminal size.

The latest session with no users can be re-attached to with screen -R. This can fail if the latest screen session has a user, so there's the -d option too, which will detach the session first if necessary.

The -D command is useful, since you can also provide the command you want to run as the first argument, so screen -D -R tail -f /var/log/foo.log will detach and re-attach to an existing session if it exists, otherwise it will create a new one reading log output.

Posted Wed Aug 6 11:00:13 2014 Tags:

Use the history command to see the whole command history of your shell:

$ history
  501  cd ../
  502  ls posts
  503  less posts/command-line-basics.mdwn 
  504  history

This shows the whole history. You can pipe it to less or grep or other tools, as needed. You can, for example, count which command you use most:

$ history | awk '{ print $2 }' | sort | uniq -c | sort -n | tail
     15 emacs
     15 man
     15 ./ripit
     18 rm
     23 python
     29 less
     31 ssh
     44 ls
     52 cd
     68 git

This isn't necessarily quite accurate, though. I use the Bash HISTCONTROL=ignoredups setting, which removes exact duplicates of command lines from the history. Thus, while I run commands like ./check and python check very often, they don't show up in the counts above.

Posted Wed Aug 13 11:00:06 2014 Tags:

screen is sometimes denounced for its bloat, usually by tmux proponents, but these features come in useful, and screen's wide availability makes it useful to learn these features.

Copying and pasting text

^A[ opens selection mode. This lets you scroll through your output and select sections by pressing enter then moving your cursor to the end of your selection and pressing enter again.

You can paste the selection by pressing ^A], which will input the previously selected text, so you can save useful snippets of a command by copying with ^A[, opening a text editor, and pressing ^A] to paste it.

Customising your caption line

If you opened multiple screens in the same session, you will see a bar at the bottom listing which screens are open. This is called the caption bar.

If you want to always see it, you need to run the caption always command.

You can either add it to your ~/.screenrc file, for it to always happen when you open a terminal, or invoke it directly on the screen command line by pressing ^A: to open the command line, then enter caption always and press enter to run the command.

Like your shell's prompt, the caption bar can be customised. This is done by entering caption string $SPEC.

There are many options possible, and referring to the screen(1) manpage is more useful than memorising them. The following example lists the number and title of all screens in the caption, and highlights the current screen in red:

caption string "%?%F%{.R.}%?%3n %t%? [%h]%?"

Screen config for complicated setups

Instead of specifying a command to run when you start your screen session, you can pass a path to a configuration file to run instead.

For example, you could put this in a config file for an irssi session:

$ cat >irssi-screen-config <<EOF
screen -t irssi irssi

With this config you can then put the following command in an appropriate place to start services, and have your computer start an irssi session in a screen session on start-up.

$ screen -D -m irssi-screen-config

You can also use the hash-bang line of a file to turn your config file into a screen script.

$ cat >irssi-screen-config <<EOF
#!/usr/bin/screen -Dm
screen -t irssi irssi

Serial console client

It is common for high-end switches and development boards to have a serial port as a back-up control interface, so when everything else is failing there's still a way to diagnose, and potentially fix a problem.

When appropriate cables have been connected, your machine will typically have added a /dev/ttyUSB0 device node to represent the connection.

Reading and writing to this device will send and recieve data along the serial port line. However, in typical embedded linux appliances the other side of the serial connection is a getty, or login console.

To communicate with this, you need a client application.

Given this article is about screen, it should come as no surprise for me to announce that screen can act as such a client.

Rather than doing screen $COMMAND, to run a command in a local tty, you run screen /dev/ttyUSB0 115200.

See the "Window Types" section of screen(1) for details about what the 115200 option is, and when you would need to change it.

This is arguably a sign of bloat, that a program about terminal multiplexing includes a serial console client, however it's convenient, as screen is widely available on Linux distros.

Filter commands

Use ^A: to open the screen command line. Enter exec COMMAND to run that command.

A sequence of !, . or : symbols before the command can be used to specify whether the input comes from your keyboard (the screen's input) or the output of the command running in your screen.

Exactly which symbols to use is a bit of a mystery, but !! replaces your shell with another program talking to the terminal. For anything else, see the screen(1) manpage.

Sending files with xmodem

xmodem is a protocol for file transfer over a serial connection.

It's old and fragile, but it's simple, so development boards sometimes have it as a fall-back for when everything else fails.

sx(1) is a tool to communicate over xmodem. It can also do the ymodem protocol by invoking it as sx --ymodem.

After opening the command line with ^A:, enter exec !! sx $FILE to send that file over xmodem.

xmodem isn't completely reliable, so it may be necessary to re-run the command.

Posted Wed Aug 20 11:00:06 2014 Tags:
Daniel Silverstone Keeping your configuration safe

What configuration do you have, and how much of it matters

On *NIX based systems, there are a number of places that your configuration might be found. Traditionally, system configuration can be found in /etc in a number of text files which are nominally human-readable and human-editable. The equivalent of those files for your specific user are found in your home directory, but rather than being conveniently kept in ~/etc they are typically kept directly in ~ but hidden from view. The *NIX idiom of hiding files from listings if they start with a full-stop (e.g. .xinitrc) means that your configuration files typically start with a full-stop and are thus referred to as your dot-files.

If you want to see just how many of these things there are, try comparing the output of ls ~ and ls -a ~. For me, the difference is 180 entries. Not every single one of those entries is a configuration file which I might care about. For example ~/.cache is simply where the applications you run store their cache data; and ~/.cabal is where your locally installed Haskell applications and libraries live. Both of those contain data it might be valuable to keep, but neither are very amenable to management outside of the tools and programs which write to them.

I like to separate configuration into that which I feel I need to keep (and/or keep synchronised between systems) and that which I do not mind if I lose. For example, I would be lost without my personalised ZShell configuration but would not lose very much sleep at all over my libreoffice personalisations going missing. In some cases this separation can also be made based on whether or not I wrote the configuration file by hand. I don't tend to feel that software-managed configuration files are precious.

How can you keep your configuration safe

Having decided which of your configuration files are precious, there now comes the realisation that, just like your programming projects, you need to keep your precious configuration files safe. And, as we have said before, that means both tracking changes and keeping copies.

There are a number of ways of achieving this. Some people like to treat their entire home directory as a revision controlled space, explicitly choosing to add files or ignore them as and when they turn up. For example, Joey Hess likes to do this, or at least he did when he wrote that blog posting. Some people like to keep specific bits of their configuration in revision control, such as John Wiegley's Emacs config. Others, such as myself, choose to keep their "precious" dotfiles in revision control. I do this in my git repository and amazingly so do Richard Maw and Lars Wirzenius -- anyone would think we were all friends who talked about this stuff a lot.

In the past I, and no doubt others (who perhaps persist in doing so to this day), kept my precious files in a tarball and periodically refreshed the tarball and sent it to my various systems. But in 1999 when I got my first real job, I was suddenly plunged into a situation where I had to deal with around 6 different platforms, in varying operating systems, across around 15 different machines and that's what finally caused me to take the plunge and keep my dotfiles in revision control. Initially I used Perforce since that was what was available at my place of work, but then I moved via CVS, Subversion, TLA and Bazaar-NG before finally ending up where I am right now (in Git).

Whatever approach you take, keeping your precious dotfiles safe will give you a sense of security and "home" whenever you have a new system you need to get a foothold in.

Keeping your safe-keeping safe

In all the above, I've not mentioned one of my favourite things -- security. You will be tempted to commit config files which contain passwords. You will be tempted to commit secret keys. You might be tempted to commit configurations which happen to leak secret information about your employer such as customer names in your folder list in your email configuration. There are a number of approaches to this issue. One is simply not to publish your dotfile repository for others to see. Another is to keep a separate clone of the repository and merge changes from your open repository to your private repository when you need to (my chosen approach). Finally you might choose to make full use of the functionality of your revision control system and have your private repository use something like git submodules to bring in your public repository as and when it needs to.

Whatever approach you choose, please remember to keep your private data private at the same time as you keep your precious configuration safe.

Posted Wed Aug 27 11:00:08 2014