In my previous post I talk about needing a TFTP server in order to serve some files to a hardware device. This post describes how I used expect to automate the process of logging into the hardware device and issue commands that copy in a config file, commit it to the device, upgrade the firmware and finally tell the device to reset to factory defaults and reboot.

Expect is a way to programmatically work with a normally interactive process. Using expect you can write a script that telnets into a system and then issues commands based on what it “sees.” Here is the script I used, with some important values removed, to automate the process of updating a number of devices.

#!/usr/bin/expect
set timeout 300
spawn telnet 192.168.1.1
expect "login: "
send "root\n"
expect "Password: "
send "tehmagicphrase\n"
expect "# "
send "cd /tmp \n"
expect "# "
send "tftp -g -r config.ini 192.168.1.159\n"
expect "# "
send "config.sh import config.ini\n"
expect "# "
send "tftp -g -r firmware.img 192.168.1.159\n"
expect "# "
send "firmware_upgrade /tmp/firmware.img 1\n"
expect EOF

The above script was saved into a file called pushConfig.expect and set as executable using ‘chmod +x pushConfig.expect’. To run the script, I powered on the device and waited for it to be ready, once ready I issued ./pushConfig.expect to start the update process.

Using expect is fairly straightforward. The most difficult part is ensuring you correctly tell expect what to look for before sending the next command. In the script above I do the following:

set timeout 300

This tells expect to wait at least 5 minutes for matching text before continuing to the next send command. What this means, is if I tell it to send some data it’ll wait up to 5 minutes to see what is in the expect line after the send. In the case of my script the firmware upgrade could take quite a bit of time and I didn’t want it to timeout so I set the value fairly high.

The next line tells expect to start a telnet session to a remote machine and then to wait until it sees:

login: 

Once it sees that it sends the username. The script continues like this until it sees EOF. At this point expect knows that the process is now complete and it exits.

By using an expect script I was able to simply power on the hardware device and wait for it to boot. Once booted I ran the script. This saved me and a co-worker a lot of time while pushing custom configurations and upgrading the firmware on a number of devices.

Expect is capable of a lot more than I used in my example and can react differently based on what it receives back from the interactive process or even loop over a series of commands. To learn more about expect try ‘man expect’ or search your favorite search engine.

My wife and I don’t watch a ton of TV but we do have a few TV series on DVD. Lately I’ve been taking the time to rip the DVDs to hard drive so we can travel with them more easily.

The problem of course is they take up a lot of space after awhile so I’ve started to compress some of them to the h264 format. I picked h264 because I like the quality and because newer Macs are able to decode h264 using hardware acceleration. One problem with the h264 format is that by itself it has no support chapter markers unlike say, the mkv container. To get around this, I wrote a couple of scripts. One of them determines how many chapters (episodes) are available on a disc and the other one does the encoding.

In order to put all of this to use you’ll need to have the HandBrakeCLI program installed on your computer. The HandBrake is site (http://handbrake.fr/) has information about how to get everything installed for your OS. This post assumes you are using Linux, Mac OS X or other UNIX like system.

Here is the script that retrieves the number of chapters on from a DVD that has been ripped to a hard drive. You’ll need to modify it for your environment. I called mine getchapters.sh but the name is arbitrary.

#!/bin/bash
HandBrakeCLI -i $1 -t 0 2>&1| grep "title 1 has" | grep chapters | awk '{print $
6}'

This script is called within another script that I called h264encode_episodic and looks like this

#!/bin/bash
chapters=`getchapters.sh $1`
if [ "$2" != "" ]; then
title=$2
else
title=$1
fi

for I in `seq 1 $chapters`
do
HandBrakeCLI -Z "High Profile" -i $1 -o ${title}E${I}.mp4 -c $I
done

Running this script in the same directory as the DVD iso or VIDEO_TS directory you will end up individual video files, one for each chapter or episode of your show. Here’s how it is called

h264encode_episodic Scrubs_S1D2.iso Scrubs_S1D2

Scrubs_S1D2.iso is the iso of the DVD I want to convert and Scrubs_S1D2 is part of how the resulting files will be named. The first episode will be named Scrubs_S1D2E1.mp4.