Shell Snippets

Symmetric GPG

1
2
#!/bin/bash
gpg --symmetric --cipher-algo=AES256 --digest-algo=SHA512 "$@"

Deterministic tar -cf

1
2
3
#!/bin/bash
export LC_ALL=C
tar --force-local --sort=name --mtime='1970-01-01 00:00:00+00:00' --owner=root --group=root --numeric-owner -cf "$1.tar" "$1"

EAC-compatible CRC of FLAC audio

1
2
#!/bin/bash
flac -s -f -d "$1" --force-raw-format --endian=little --sign=signed -o - | rhash --printf='%C\n' -

MIDI to PulseAudio (via GStreamer)

1
2
#!/bin/bash
timidity --output-24bit -A120 "$1" -Ow -o - | gst-launch-0.10 filesrc location=/dev/stdin ! decodebin ! pulsesink > /dev/null

GNOME-GPG with fallback

1
2
3
4
5
6
#!/bin/bash
if [[ -z "$DISPLAY" ]]; then
  gpg "$@"
else
  gnome-gpg "$@"
fi

X11 Mouse Ungrab

1
2
3
#!/bin/bash
setxkbmap -option grab:break_actions
xdotool key XF86Ungrab

notify-send for MacOS

Based on notify-send(1) from libnotify-bin. Example: notify-send "title here" "longer description here"

1
2
3
4
5
6
#!/bin/bash
osascript \
  -e 'on run argv' \
  -e 'display notification (item 2 of argv) with title (item 1 of argv)' \
  -e 'end run' \
  "$@"

Sort output of du --si

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/python
import argparse
import sys 

SIZES = {"k": 1000, "K": 1000, "M": 1000000, "G": 1000000000}

def stdin_lines():
    while True:
        try:
            yield raw_input()
        except EOFError:
            return

def keyfunc(line):
    raw_size, dir = line.split("\t", 1)
    for suffix, size in SIZES.items():
        if raw_size.endswith(suffix):
            return float(raw_size[:-1]) * size
    return int(raw_size)

def main(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument(
            "-r", "--reverse", action="store_true", default=False,
            help="reverse the result of comparisons")
    args = parser.parse_args(argv[1:])
    for line in sorted(stdin_lines(), key=keyfunc, reverse=args.reverse):
        print line

if __name__ == "__main__":
    sys.exit(main(sys.argv))

Multi-threaded Python SimpleHTTPServer

Equivalent to python -m SimpleHTTPServer but supports concurrent connections.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/bin/python
import argparse
import BaseHTTPServer
import SimpleHTTPServer
import SocketServer
import sys

class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
    pass

def main(argv):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--port", action="store", default=8000, type=int, nargs="?",
        help="Specify alternate port [default: 8000]")
    parser.add_argument(
        "--iface", action="store", default="127.0.0.1", type=str, nargs="?",
        help="Specify iface [default: 127.0.0.1]")
    args = parser.parse_args(argv[1:])
    server_address = (args.iface, args.port)
    srv = ThreadedHTTPServer(server_address, SimpleHTTPServer.SimpleHTTPRequestHandler)
    sa = srv.socket.getsockname()
    print "Serving http://%s:%r ..." % (sa[0], sa[1])
    srv.serve_forever()

if __name__ == "__main__":
    sys.exit(main(sys.argv))
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python
import sys

def main(argv):
    if len(argv) != 2:
        sys.stderr.write("usage: %s PID\n" % (argv[0],))
        return 1
    if argv[1] != "self":
        try:
            int(argv[1])
        except ValueError:
            sys.stderr.write("invalid process ID %r (expected integer or 'self')\n" % (argv[1],))
            return 1
    with open("/proc/%s/environ" % (argv[1],)) as fp:
        content = fp.read()
    for var in content.split(b"\x00"):
        if var:
            print var

if __name__ == "__main__":
    sys.exit(main(sys.argv))