Artikel getaggt mit shell

Running a script with unshared mount namespace

When writing system integration tests it often happens that I want to mount some tmpfses over directories like /etc/postgresql/ or /home, and run the whole script with an unshared mount namespace so that (1) it does not interfere with the real system, and (2) is guaranteed to clean up after itself (unmounting etc.) after it ends in any possible way (including SIGKILL, which breaks usual cleanup methods like “trap”, “finally”, “def tearDown()”, “atexit()” and so on).

In gvfs’ and postgresql-common’s tests, which both have been around for a while, I prepare a set of shell commands in a variable and pipe that into unshare -m sh, but that has some major problems: It doesn’t scale well to large programs, looks rather ugly, breaks syntax highlighting in editors, and it destroys the real stdin, so you cannot e. g. call a “bash -i” in your test for interactively debugging a failed test.

I just changed postgresql-common’s test runner to use unshare/tmpfses as well, and needed a better approach. What I eventually figured out preserves stdin, $0, and $@, and still looks like a normal script (i. e. not just a single big string). It still looks a bit hackish, but I can live with that:

set -e
# call ourselves through unshare in a way that keeps normal stdin, $0, and CLI args
unshare -uim sh -- -c "`tail -n +7 $0`" "$0" "$@"
exit $?

# unshared program starts here
set -e
echo "args: $@"
echo "mounting tmpfs"
mount -n -t tmpfs tmpfs /etc
grep /etc /proc/mounts
echo "done"

As Unix/Linux’ shebang parsing is rather limited, I didn’t find a way to do something like

#!/usr/bin/env unshare -m sh

If anyone knows a trick which avoids the “tail -n +7″ hack and having to pay attention to passing around “$@”, I’d appreciate a comment how to simplify this.

Tags: , , , , , ,

Presentations of shell commands

Today I was sitting in the plane from Dresden to San Francisco, and worked on my DKMS demo for the Linux Foundation summit. DKMS is a command line tool for managing device driver packages.

I wondered how to present this. The commands and features I wanted to show are quite complex, and typing all of them during the presentation is too cumbersome. Besides, I’m just a lousy typer when someone else is watching. On the other hand, pasting them into classical slides is too static; I find it much easier to understand something that reveals itself step by step.

So what I needed is to prepare the chain of commands in advance, and then send them through an interactive “step by step” interpreter. A quick apt-cache search did not reveal any readymade solution, thus I hacked together a small script “shellpresent” which does exactly that:

  • a line with a command gets echoed, then it waits for a keypress, then runs the command and waits for another keypress (so that you can explain the output)
  • a comment line starting with # is printed in green, and doesn’t wait for a keypress
  • a blank line clears the screen
  • commands are prepended by a red “$” sign to indicate a command prompt

It now does exactly what I want. Perhaps it is useful for someone else out there as well.

Tags: , ,