about me
zcta bitmap

A small experiment which encodes zip codes and states in a 600kB PNG image.

tree viz

MkTree is a tool for visualizing tree and graph data. Efficiently handles pre-load large tree structures (10-50k nodes) without server calls. The goal is to merge this with another graph project I've been working on for arbitrary graph data.

timing app

Lapper is a small web app for tracking the splits of multiple participants in a race/workout. The goal is to build this out into a mobile-friendly meet-management tool, as well as a way to keep track of workouts and races over the course of a season.


A js/canvas-based app for simple calculations and graphing of algebraic functions. The expression-parsing engine was the most interesting part to write. Being able to work through problems in a save-all-history workbook (using Local Storage) is the most useful part.

Potential future work includes LaTeX-like formatting engine, further functionality to replace a graphing calulator.

a history of storage cost

IT'S BEEN almost five years since I first looked at the history of hard drive cost, and a lot has changed in the market. The most salient change is that, on average, drives are no longer getting bigger. For a long time, one of the driving factors in consumer hard drive innovation was the need for more space, and that simply isn’t a huge force anymore. Increasingly, we're focusing our attentions on speed, reliability, and accessibility. There are several external forces that have shifted the focus away from the mantra of "more space cheaper", and it’s hard to imagine the industry ever pivoting back...

hist - bash history forever!

When I first started spending a lot of time in a shell, I remember often getting a sinking feeling when a command I needed had just fallen off the history stack. Sure, you can adjust the number of entries stored in your bash history, but that didn't seem good enough.

So I wrote a utility called hist. It allows me to do some things that are not possible with the standard builtin as well as some things that are not otherwise easy or straightforward:

  • retain my history forever and aggregate it across computers
  • immediately see commands that were executed in other terminal sessions.
  • retain with each history entry information including: shell PID, exit code, and pwd at the time of execution.
  • query my entire history efficiently using hist -ag $REGEXP, where $REGEXP can include the datetime, shell id, directory of execution or any part of the command

It's simple to add hist to your bash environment:

  • clone the hist repo:

    git clone https://github.com/mkomo/hist.git
  • put hist in an executable path:

    ln -s hist/hist ~/bin/hist
  • register hist in your bash prompt command:

    function mkomoprompt {
        eval "`hist -r`"
    export PROMPT_COMMAND=mkomoprompt

now all of your history will be stored forever in ~/.bash_eternal_history and you can query it at any time with commands like:

# every time you've executed the apt-get command on this machine
hist -ag apt-get


# every time command you've executed in this directory during the current shell session
hist -cg `pwd`

and see results like this:

#pid, date, time, exit status, directory, command
16420   2014-11-23 13:24:04 0   /home/mkomorowski   sudo apt-get install compiz-plugins-extra
16420   2014-11-23 13:24:53 130 /home/mkomorowski   sudo apt-get install compiz-plugins-extra
11962   2014-11-26 13:00:54 100 /home/mkomorowski   sudo apt-get install cvt
11962   2014-12-05 03:36:08 0   /home/mkomorowski   sudo apt-get install pepperflashplugin-nonfree
25065   2014-12-07 10:21:15 0   /home/mkomorowski/workspaces    sudo apt-get install vlc


what's your ideal weather?

I've always been unsatisfied by those "Ten Cities with Unbeatable Weather"-type articles that you see in magazines every once in a while. Sure, everyone knows San Diego is nice, but I wanted something a little bit more quantifiable.

I compiled climate data from around the country (averages, records, precipitation) and wrote some code that ranked locations based on my own criteria for what constitutes the best weather. The end result was a set of maps that gave me an idea about which areas of the country are nicest (hint: the magazines weren't too far off).

ldapsearch oneliners

ldapsearch is a command line tool for querying ldap. Sometimes you want to retrieve directory information and don't have access an administrative interface, or you want something that's scriptable -- that's when ldapsearch comes in handy.

handy environmental variables:

export LDAP_HOST="ldap01.example.com"
export LDAP_SEARCH_BASE="dc=foo,dc=bar" # the search base for your searches
export LDAP_BIND_DN="$USERNAME@foo.bar" # the DistinguishedName to use when binding to the ldap host

export LDAP_PASSWORD_ARG="-w" #prompts everytime the command is run
export LDAP_PASSWORD_ARG="-W mysecurepassword" #stores your password to the ldap server in memory (probably a bad idea)

here are some one-liners that I use pretty frequently:

#list all groups
#usage: ldaplistgroups
alias ldaplistgroups='ldapsearch -x -h $LDAP_HOST -b "$LDAP_SEARCH_BASE" -D $LDAP_BIND_DN "(objectcategory=group)" * $LDAP_PASSWORD_ARG | grep "^dn:" | sed "s/.* CN=\([^,]*\),.*/\1/" | sort'

#list all members of the given group
#usage: ldapmembership "engineering-team"
ldapmembership() { ldapsearch -x -h $LDAP_HOST -b "$LDAP_SEARCH_BASE" -D $LDAP_BIND_DN "(&(objectcategory=user)(memberof=CN=$1,OU=Distribution Groups,$LDAP_SEARCH_BASE))" * $LDAP_PASSWORD_ARG | grep ^mailNickname: | sed "s/mailNickname: //" | tr [A-Z] [a-z] | sort }

#show the given user's entire ldap entry
#usage: ldapuser "Matt Komo"
ldapuser() { ldapsearch -x -h $LDAP_HOST -b "$LDAP_SEARCH_BASE" -D $LDAP_BIND_DN "(&(objectcategory=user)(CN=$1))" $LDAP_PASSWORD_ARG }

and here is a slightly more complicated bash script that I use to retrieve all groups that a user is a member of (including recursive groups):


#usage: ldapallgroups "Matt Komo"

echoerr() { echo "$@" 1>&2; }

while [ "$(echo $QUERY | wc -c)" -gt "6" ]; do

    LDG=$(ldapsearch -x -h $LDAP_HOST -b "$LDAP_SEARCH_BASE" -D $LDAP_BIND_DN "$QUERY" 'memberOf' $LDAP_PASSWORD_ARG | grep "^memberOf: " | sed "s/memberOf: \([^,]*\),.*/\1/")
    if [ -n "$LDG" ]; then
        echoerr "next order groups: "
        echo "$LDG"
    QUERY=$(echo "(|($LDG))" | tr "\n" "&" | sed 's/\&$//' | sed "s/\&/)(/g");
    echoerr "next query: $QUERY"
tour de taco

Three dudes. Three bikes. 127 miles. 18 mighty tacos.