Jerith online [entries|archive|friends|userinfo]
jerith

[ website | jerith.za.net ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Ubuntu, Erlang and Launchpad [Jan. 31st, 2009|05:11 pm]
[Tags|, , , ]

Ubuntu Hardy has an old version of Erlang. Ordinarily this wouldn't be a problem, but it turns out that R12B (the current release) added a few libraries that I use in my Project Euler solutions. Upgrading to Intrepid isn't really something I want to do at the moment (for reasons that I'll happily discuss over a beer) and language interpreters don't get backported.

This left me with two options: Rewrite my code to not use the new regular expression library and the not-quite-an-array data structure that Hardy's version of Ubuntu lacks or build and install a modern Erlang from source. Fortunately, a little investigation turned up a third: Launchpad's Personal Package Archives.

I was surprised at easy it is to rebuild a deb source package and get it into Launchpad's build system. Since I didn't have to make any changes, it was merely a matter of downloading the source files from Intrepid's Launchpad page, adding a changelog entry to get my own version number and email address (for pgp signing) in there and running a couple of commands to build and upload the new source package.

There are a couple of caveats to adding packages to a PPA, though. It's generally a good idea to at least build and test the binaries locally before uploading. Not only is this polite (in that you're less likely to tie up shared build resources with broken code), it also saves time waiting around for builds to be scheduled only to discover that they're broken. In addition, there's a bit of a lag between Launchpad claiming that a build is complete and the binaries actually being available. In particular, it took quite a while for launchpad to make my i386 packages (which includes all the architecture-independent stuff) available despite announcing a successful build in the web interface.

All in all, I'm very impressed with PPAs. In half an afternoon, I have managed to add custom (sort of) versions of several packages to my PPA and install them on my local machine. Not only that, but they're available for anyone who wants to use them with no extra effort on my part.
LinkLeave a comment

Higher order functions in bash [Jul. 13th, 2007|10:07 am]
[Tags|, , ]

I recently had occasion to refactor a bunch of bash scripts, and one of the problems was that certain loop constructs were cropping up a lot. A quick search didn't turn up a way to do higher order functions in bash, so I (re)invented one:
higher_order() {
    # some code
    eval "$1"
    # some more code
}

The eval evaluates the code passed as a parameter, although for anything nontrivial this should probably be a function name.

Here's a slightly more concrete example:
do_twice()
{
    for i in `seq 2`; do
        eval "$1"
    done
}

hello() {
    echo "Hello $1"
}

do_twice 'hello world'

Update:

I wrote up a more complete version over at my website and have just added a bunch more toys to it.
Link4 comments|Leave a comment

Set operations in bash [Mar. 9th, 2007|02:01 pm]
[Tags|, , ]

This post is some Linux geekery inspired by a problem a coworker solved today.

The problem was that he had a file full of stuff (one item per line) and another file full of partially overlapping stuff and wanted a list of the stuff that appeared in the first file but not the second, which is essentially set difference. This was to be done in bash by preference, as it was part of a longer script and perl/ruby one-liners look ugly in scripts. You may want to take a few seconds to try figure this one out before you look at the explanation below.

cat foo bar bar | sort | uniq -u

Starting at the end, uniq -u outputs only lines that have multiple consecutive copies in the input. Since the lines need to be consecutive, the input needs to be sorted. The cat portion is the trick. We cat bar twice to make sure that it will never contribute a line to the output. Combined with foo, this will give us one copy of any line that appears only in foo, two copies of any line that appears only in bar and three copies of any line that appears in both. There is only one real requirement, and that is that foo contains no duplicates to begin with. This is fairly trivial to arrange and is left as an exercise for the reader.

This is not the only set operation possible, however. You can also do the following:

  • Intersection (requires no duplicates in either file): cat foo bar | sort | uniq -d
    (Have a look at man uniq for details on the flags it takes.)

  • Union (no input restrictions): cat foo bar | sort | uniq
    (The sort and uniq are not strictly required here, but they keep the output format the same. Also, the sort | uniq can be replaced with sort -u for a small efficiency gain.)

Complements don't really make much sense since you can use difference to filter out the set you don't want from pretty much everything. Shell scripts seldom need to deal with infinite sets and they'd probably take too long to run anyway...

This post brought to you courtesy of caffeine, day-job problems and mithrandi.
LinkLeave a comment

Yay for bash! [Sep. 7th, 2006|07:36 am]
[Tags|, ]

I have an mp3 player that only sorts on the first n characters of the filename, where n is small. (I suspect 6, due to the nature of the filesystem, but I've never bothered to check.) Thus, despite my files being numbered at the end of the file and thus sorting fine on any sane system, the mp3 player sees them in some crack-addled order only it understands.

A few seconds of thought, one man-page reference and one debugging cycle later, the following solution presented itself:
i=0; for f in *.mp3; do i=$(($i+1)); ln $f tmp/e`printf "%02d" $i`-$f; done

This is just cool on so many levels.

The first three characters of the new filename give me sorting. The sort order is provided by the filesystem. Numbering is padded to two digits, although that's trivial to change if you have more than 99 files. The niftiest thing, though, is that they're hardlinked. This means that they take up no extra hd space (which is handy if the audiobook I want to listen to is several hundred megs) and if I move them (rather than copy) it's trivial to keep track of what I've already listened to.
Link1 comment|Leave a comment

navigation
[ viewing | most recent entries ]

Advertisement