This is a collection of useful free software and commands for various purposes, that didn't quite fit into my setup description.


Custom live image

Sometimes it's quite useful to have your own custom live system image on a USB stick or a CD, e.g. to save a broken installation or to do maintenance work that cannot be done when the system is running. Building a custom image makes it possible to include software packages that are not included by default and to change the general configuration to your liking.

Set up a basic config according to the manual. If the correct directory structure is there and you are able to build the default image, add a list with additional packages you want.

My config command looks like this:

lb config --bootappend-live \
            "boot=live config locales=de_DE.UTF-8 keyboard-layouts=de username=wolfi" \
          --debian-installer live

This command ensures a that the image has a German locale and keyboard layout. I also specify a custom user name to login. The default password is "live". With this config, it's possible to install the system to a disk.

Package building

When I build a Debian package from its sources, I only sometimes want to make actual changes to the source code. In most cases, I want to do a simple backport of a newer package from Testing or Unstable. So it's very annoying if the package build includes test cases that take quite some time to run. You can add DEB_BUILD_OPTIONS=nocheck to your dpkg-buildpackage command to skip the test cases.


I do nearly all my text editing in Emacs. I write all my code in Emacs, edit configuration files in Emacs, write LaTeX documents with the great AUCTEX package and do my email with mu4e. The text you are reading right now was also written in Emacs. You can find a partially cleaned up version of my Emacs config file here. I use the "tomorrow" theme. Packages are maintained with El-Get.

To securely send email in Emacs, I do certificate pinning with GnuTLS as described here. My mail server uses Let’s Encrypt, so I have to do the pinning every two months. The procedure is as follows:

$ gnutls-cli --tofu --crlf --starttls -p 587
EHLO localhost

Then press Ctrl-D.

If you work with others on a software project or if you want to write clean code in general, it's important to properly use whitespace. With the command whitespace-cleanup, you can get rid of unnecessary whitespace at the end of lines or in otherwise empty lines.

Open a file as root in Emacs:

C-x C-f /sudo::/path/to/file

Files and storage

Count number of words in a PDF document:

pdftotext <FILE> - | tr -d '.' | wc -w -

pmount can be used to manually mount removable mass storage as normal user.


View network connections continously:

netstat -t -u -c

List the programs that currently use a specific network interface:

sudo nethogs <INTERFACE>

Profiling applications

Collect function calls with callgrind without fancy options:

valgrind --tool=callgrind <APP>

Results can be viewed in KCachegrind.


I do all my video editing and the occasional 3D modeling with the allrounder Blender. Vector graphics are created in Inkscape.


Geeqie is a really nice and fast program to browse the RAW image files of your camera. I get the best out of my RAW images by editing them with Rawtherapee. Gimp is used for everything else that Rawtherapee can't do. HDR images can be created with Luminance HDR.

If I want to publish an image on the web, I first export it as JPEG, remove EXIF data with exiftool -all= IMAGE.jpg and optimize it with jpegoptim -s IMAGE.jpg.

Record screen

Set the screen size with the -s option: wuxga for 1920x1200 and wxga for 1366x768.

avconv -f x11grab -s wuxga -r 25 -i :0.0 -qscale 5 -an OUTPUT.avi


I build the Openwrt images for my routers from source. This way I can benefit from the security updates that are backported to the stable branches. The official prebuilt images are normally not updated when there are security issues. Additionally, I can add packages to the image, so I don't have to rely on the binary package manager. This also saves space. To update the sources, a few steps are needed:

git pull
./scripts/feeds update -a
./scripts/feeds install -a

The newly build images can be found in the bin folder in a directory with the name of the platform the router is based on.

I use Unbound as a recursive DNS resolver on my routers for all devices that are behind it. After upgrading the routers, it's necessary to sync the time. Otherwise, resolving DNS entries will fail.


The phone's storage can be manually mounted with jmtpfs /media/phone/ and unmounted with fusermount -u /media/phone.

I work on a Replicant version based on CyanogenMod 13. Alpha releases are tagged on the stable branch. There are too many git repositories in order to do the tagging manually, so I came up with two commands. First to add signed tags to all the repos that are directly mirrored from CyanogenMod:

repo forall $(repo forall -c ' echo "$REPO_REMOTE$REPO_PROJECT" | grep cm-mirror | cut -c10-') \
            -c ' git tag -s replicant-6.0-alpha-0002 -m "second alpha release of Replicant 6.0" && \
                 git push$REPO_PROJECT replicant-6.0-alpha-0002 '

Then sign all the modified repos:

repo forall $(repo forall -c ' echo "$REPO_REMOTE$REPO_PROJECT" | grep fossencdi | cut -c10-') \
            -c ' git tag -s replicant-6.0-alpha-0002 -m "second alpha release of Replicant 6.0" && \
                 git push$REPO_PROJECT replicant-6.0-alpha-0002 '

GDB debugging

Set the path of your Android GDB installation in the development repo, e.g.:

diff --git a/scripts/gdbclient b/scripts/gdbclient
index 8ff9ae9..5357d38 100755
--- a/scripts/gdbclient
+++ b/scripts/gdbclient
@@ -34,7 +34,7 @@ function gdbwrapper()
     local GDB_CMD="$1"
     shift 1
-    $GDB_CMD -x "$@"
+    toolchain/gdb/install/bin/arm-elf-linux-gdb -x "$@"

 function gdbclient() {

Get a gdbserver binary, push it to the device and start it for the binary you want to monitor. An example for debugging surfaceflinger:

adb push gdbserver /system/bin/
adb shell "gdbserver /system/bin/surfaceflinger" &

Then run the gdbclient script with the PID as option.