Category Archives: Code

Compound conditionals in CFEngine

I have been working with CFEngine for about half a year no in my new role. CFEngine is known to have a steep learning curve. I can’t disagree with that sentiment, I can however say that it is intuitive.

This tip though covers compound conditionals and classes. CFEngine uses classes to define a desired end state.

In cfengine this can difficult because the syntax is very restrictive.

Set Outlet State on APC PDU

For various reasons I needed a script to change the state on an APC PDU. You need to make sure to set your private string and enable SNMP. For some reason snmpset doesn’t work when someone is logged into the management.

PRIVATE='<fill this out>'
IP='<fill this out>'
SNMPCMD="/usr/bin/snmpset -v 2c"
PROG=$(basename ${0})
usage() {
        cat <<EOF
        "${PROG} [-h] -i <ip address> -o <outlet number> -s <on|off|reboot>"
        -h: usage|help
        -i: ip address of apc powerstrip
        -o: outlet # from 1-8
        -s: desired state (on,off,reboot)
        exit 1
while getopts hi:o:s: f
    case "${f}" in
        h) usage
        i) IP=${OPTARG}
        o) OUTLET=${OPTARG}
#test for mandatory cmdline args
if [ -z "${IP}" ] || [ -z "${OUTLET}" ] || [ -z "${STRING_STATE}" ] ; then
        echo "missing necessary commandline arg"
# 1 = on, 2 = off,  3 = reboot
case "${STRING_STATE}" in
        [Oo][Nn]) INT_STATE=1
        [Oo][Ff][Ff]) INT_STATE=2
        reboot | REBOOT) INT_STATE=3
        *) echo "${STRING_STATE} not a valid option"; exit;
if [ "${OUTLET}" -lt "1" ] || [ "${OUTLET}" -gt "8" ]; then
        echo "${OUTLET} is out of bounds, must be 1<outlet<8"; exit;
"${SNMPCMD}" "-c ${PRIVATE}" "${IP}" "${OID}${OUTLET}" integer "${INT_STATE}"

Sorting files into folders based on exif date using python

I like to sort my pictures based on the date they were taken. It can get pretty laborious to do so by “hand.”

Here is a little script I whipped together in about 30 minutes to make my life just a bit easier. Ain’t it grand being able to simplify your life through programming!

Caveat Emptor:  This is by no means a finished product, but merely a rough draft.

# exif_sort[January 2012] / martin gehrke [martin AT]
# sorts jpg/jpegs into date folders based on exif data
from PIL import Image
from PIL.ExifTags import TAGS
import sys, os, glob
def format_dateTime(UNFORMATTED):
    return DATE.replace(':','')
def get_exif(fn):
#see <a href=""></a>
    ret = {}
    i =
    info = i._getexif()
    for tag, value in info.items():
    decoded = TAGS.get(tag, tag)
    ret[decoded] = value
    return ret
def sortPhotos(path):
    PHOTOS = []
    EXTENSIONS =['.jpg','.jpeg']
        PHOTO = glob.glob('*%s' % EXTENSION)
    for PHOTO in PHOTOS:
        DATE = format_dateTime(get_exif(PHOTO)['DateTime'])
        if not os.path.exists(DATE):
        os.rename(PHOTO, "%s\%s" % (DATE,PHOTO))
if __name__=="__main__":
    PATH = sys.argv[0]
    if PATH == '': PATH = os.getcwd()

PXE to installed OS

Sometimes you unintentionally PXE boot while you would like to just let the local OS boot. This can happen if you have the boot order mixed up in BIOS or you hit a stray key during POST. Either way here is a helpful little entry to have in your PXE menu.

label harddisk
        localboot 0x80
        append SLX=0x80

0x80 – first partition of first HDD
0x81 – second partition of first HDD
0x00 – first floppy drive

Bash, aliases, and command line arguements

I was recently doing some work with gzip’d files. It got kind of repetitive to keep typing

gunzip file
head file
gzip file

I know there is a zcat but I don’t want to have to type

zcat file | head


You can create aliases in your .bashrc file. These are quick shortcut commands.
The following does not work

alias zhead='zcat $1 | head' #does NOT work

In order for this to work you have to create a function in your .bashrc and call it from the alias.

function zh(){
    zcat $1 | head
alias zhead='zh'


Yanked from

  • -mtime +60 means you are looking for a file modified 60 days ago.
  • -mtime -60 means less than 60 days.
  • -mtime 60 If you skip + or – it means exactly 60 days.

10 Quick Tips

I would not agree that these are usage habits, or even unix specific. But they are nifty.

  • Make directory trees in a single swipe.
  • Change the path; do not move the archive.
  • Combine your commands with control operators.
  • Quote variables with caution.
  • Use escape sequences to manage long input.
  • Group your commands together in a list.
  • Use xargs outside of find .
  • Know when grep should do the counting — and when it should step aside.
  • Match certain fields in output, not just lines.
  • Stop piping cats.