Notes: Linux administration and use

June 09, 2015

These are my notes from maintaining a laptop Linux system. They're based on NixOS, but should generally work other distributions as well.

HTTPS with Lets Encrypt

Install certbot:

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

Run certbot:

/certbot-auto certonly

Combine the resulting fullchain.pem and privkey.pem files:

cd /etc/letsencrypt/live/domain-name
cat fullchain.pem > all.pem
cat privkey.pem >> all.pem

Add all.pem to haproxy.cfg.

Simple HTTP file server command

python -m SimpleHTTPServer 8080

Email

To email Markdown-based content to folks, use xclip:

$ markdown | xclip -i
## Very important to-do list

* [x] Learn Markdown
* [x] Send some Markdown in an email
^D

Then paste it into an HTML-aware client.

Record windows as .gifs

Make a script to launch a floating terminal, then launch byzanz-record.

record.sh:

#!/bin/bash

if [ "$#" -ne 1 ] ; then
  echo "Usage: $0 <output.gif>"
  exit 1
fi

if [ -f $1 ] ; then
  echo "Output file $1 already exists."
  exit 2
fi

xwininfo=$(xwininfo -shape)

getnum() {
  echo "$xwininfo" | grep "$1" | tr -cd [:digit:]
}

x=$(getnum "Absolute upper-left X:")
y=$(getnum "Absolute upper-left Y:")
w=$(getnum "Width:")
h=$(getnum "Height:")

x=$((x + 1)) # the +1 excludes the xmonad border
y=$((y + 1)) # the +1 excludes xmonad border

byzanz-record $@ -x $x -y $y -w $w -h $h

Encrypted USB drive

Creating:

# dd if=/dev/urandom of=/dev/sdx
# cryptsetup -y -v luksFormat /dev/sdx
# cryptsetup luksOpen /dev/sdx sdx
# mkfs.ext4 /dev/mapper/sdx
# cryptsetup luksClose /dev/mapper/sdx

Mounting:

$ udisksctl unlock -b /dev/sdx
Passphrase:
Unlocked /dev/sdx as /dev/dm-x
$ udisksctl mount -b /dev/dm-x
Mounted /dev/dm-x at /run/media/bar/baz

Unmounting:

$ udisksctl unmount -b /dev/dm-x
$ udisksctl lock -b /dev/sdx

Record video from a camera

ffmpeg -f oss -i /dev/dspX -f video4linux2 -s 640x480 -i /dev/video0 out.mpg

haproxy

/etc/haproxy/haproxy.cfg:

# After the standard "global" and "defaults" sections

userlist my_users
  user usernamegoeshere insecure-password passwordgoeshere

frontend http-in
  bind *:80
  default_backend my_service

backend my_service
  acl my_acl http_auth(my_users)
  http-request auth realm my_service if !my_acl
  server my_service1 localhost:9999 check inter 5000

UFW and mosh

# ufw allow 60000:61000/udp

Firefox

Disable mouse middle-button URL browsing

In about:config, set middlemouse.contentLoadURL to false.

irssi

Auto-join all currently open channels:

/alias addallchannels script exec foreach my \$channel (Irssi::channels()) { Irssi::command("channel add -auto \$channel->{name} \$channel->{server}->{tag} \$channel->{key}")\;}

Followed by:

/addallchannels
/save

Pandoc

To convert a Markdown file into something presentable as a Web page:

pandoc -H _head.html -s -f markdown -o index.html README.md

To convert a Markdown file into Slidy slides:

pandoc -s -f markdown -t slidy -o index.html README.md

List open ports

$ netstat -lntup

Plot functions

plot.gnu:

#!/usr/bin/env gnuplot

reset

set border linewidth 1.5
set style line 1 linecolor rgb '#0060ad' linetype 1 linewidth 2  # blue
set style line 2 linecolor rgb '#dd181f' linetype 1 linewidth 2  # red

set key at 85,26.5

set xlabel 'this is the x axis'
set ylabel 'this is the y axis'

set xrange[0:10]
set yrange[-10:10]

set xtics ("Zero" 0, "Three" 3, "Six" 6, "Nine" 9)
set ytics 2
set tics scale 0.75

f(x) = sin(x)
g(x) = x

set terminal svg size 640,480 fname 'Verdana,Helvetica,Arial,sans-serif' fsize '10'
set output 'plot.svg'
plot f(x) title 'sin(x)' with lines ls 1, \
     g(x) title 'x' with lines ls 2

set terminal pngcairo size 640,480 enhanced font 'Verdana,10'
set output 'plot.png'
plot f(x) title 'sin(x)' with lines ls 1, \
     g(x) title 'x' with lines ls 2

Handy patterns of commands

Copy a password to the clipboard, then clear the clipboard after ten seconds:

function passw() {
  pass "$1" | head -n 1 | xclip -i
  (sleep 10 ; echo '' | xclip -i) &>/dev/null &
}

Pass the output of pandoc directly to Firefox:

function panfox() {
  pandoc $1 | firefox "data:text/html;base64,$(base64 -w 0 <&0)"
}

Throw away all local git changes and restore to HEAD:

function git-panic() {
  git checkout -f master
  git clean -fdx
}

Get a "short" git SHA:

function git-short() {
  git rev-parse --short HEAD
}

Compile and run a Java file using Nix:

function java-run() {
  filename=$(basename "$1")
  classname="${filename%.*}"
  args="${@:2}"
  nix-shell -p jdk --run "javac $filename && java $args $classname"
}

Remove all local Docker images and instances:

alias docker-rm-rmi='docker rm -f $(docker ps -a -q) && docker rmi -f $(docker images -q)'

Crop and border images:

alias crop='convert -trim -bordercolor red -border 1'
alias border='convert -bordercolor red -border 1'

Run a Nix shell with ghc and some Haskell packages:

function nix-haskell() {
  nix-shell -p "haskellPackages.ghcWithPackages (pkgs: with pkgs; [$@])"
}

Prune local merged git branches:

function git-prune() {
  git branch --merged | grep -v "\*" | grep -v master | xargs -n 1 git branch -d 2>/dev/null
  git remote prune origin
  git branch -a
}

Add a delay to an animated .gif file:

function delay() {
  if [ "$#" -ne 3 ]; then
    echo "Usage: delay <input.gif> <output.gif> <duration>"
  else
    INPUT=$1
    OUTPUT=$2
    DELAY=$3
    convert "$INPUT" \( -clone -1 -set delay $DELAY \) +swap +delete "$OUTPUT"
  fi
}

Run codedown on a Scala file:

scodedown() {
  if [ "$#" -lt 1 ]; then
    echo "Usage: scodedown <file.md>"
  else
    if [ -f "$1" ]; then
      cat "$1" | codedown scala | xargs -0 scala "${@:2}" -e;
    else
      curl -sL "$1" | codedown scala | xargs -0 scala "${@:2}" -e;
    fi
  fi
}