Category Archives: Geeky

Technical stuff about Perl, Linux and computing & technology in general.

Configure CPAN.pm to use sudo to install

I prefer to run CPAN.pm as a normal user and have it use sudo just for the actual installation, rather than running tests etc as root.

I have an annoying habit of forgetting the option names , so I’m posting this here for my reference, but might be useful for other people too.

To do that, do the following from a CPAN shell:


o conf make_install_make_command 'sudo make'
o conf mbuild_install_build_command 'sudo ./Build'
o conf commit

Also, whilst documenting that, to set your preferred CPAN mirror:


o conf urllist unshift ftp://mirrors.uk2.net/pub/CPAN/
o conf commit

Texas Instruments DMCA abuse over signing keys

Paul Dixon, owner of pastebin.com, received a DMCA takedown order from Texas Instruments, relating to a pastebin post that a user had submitted to pastebin.com, "containing the signing keys for a range of Texas Instruments calculators which, if I understand correctly, allow you to digitally sign a replacement operating system so that the hardware will accept it"

They seem to overlook the fact that Paul is in the UK, and pastebin.com is hosted in the UK, so throwing DMCA notices around is a little pointless, acheiving nothing more than making themselves look bad.

In fact, the Streisand Effect pretty much guarantees that such attempts backfire, and result in nothing more than causing the material they desire to censor to be more widely distributed.

In fact, with information leaked to wikileaks, it’s a lost cause already.

When will companies learn that attempting to artificially control what people can do with their devices which they bought and legally own needs to stop, and that the Internet routes around censorship attempts?

SSH key for Subversion but nothing else

I needed to create an account with an SSH key which could be used for Subversion, but nothing else.

The solution – forced commands with the SSH key – on the host machine, make ~/.ssh/authorized_keys look like:


command="/usr/bin/svnserve -t",from=""

Dumping this here mostly for my future reference, and for anyone who might find it useful.

This means the SSH private key on the client can be used by Subversion to check code in/out, but cannot be used for anything else (as SSH’ing to the host machine with that key simply starts ‘svnserve’, regardless of what the client asked for).

Mounting a Linux software RAID partition directly

I needed to mount a Linux software RAID partition directly to copy the data from it; it wasn’t being recognised as a RAID device (it didn’t appear in /proc/mdstat, only my newly-created array did), and attempting to mount it gave me:

[davidp@supernova:~]$ sudo mount /dev/sdc4 /mnt/tmp
mount: unknown filesystem type 'mdraid'

To get round that, I had to tell mount the filesystem type that was actually in use:

sudo mount -t xfs -o ro /dev/sdc4 /mnt/tmp

(I mounted it read-only just in case this approach wasn’t going to work; I don’t want to write to it anyway.)

Might be useful for anyone Googling (it’s pretty obvious, but it made me think for a few minutes… it’s getting late!)

The partition type appeared as ‘Linux raid autodetect’:

Disk /dev/sdc: 200.0 GB, 200049647616 bytes
255 heads, 63 sectors/track, 24321 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x7bf29ced

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1   *           1         871     6996276   fd  Linux raid autodetect
/dev/sdc2             872         995      996030   fd  Linux raid autodetect
/dev/sdc3             996        1119      996030   82  Linux swap / Solaris
/dev/sdc4            1120       24321   186370065   fd  Linux raid autodetect

Subversion – show commit details when editing commit message

Something I’ve wanted to do for a while is get the list of changed files and a diff into the commit message in my editor when I make a commit with Subversion.

With Git, you can pass the -v (verbose) option when committing, and the commit message you edit will include diffs as well as the list of modified files.

Subversion provides no such option, so I put together a little wrapper shell script to do this for me.

The script provides a function named svncommit (which I alias to just ‘ci’ for supreme shortness :) ).

When used, after the “–This line, and those below, will be ignored–” marker line, the list of files and then diffs will be inserted, as shown in the screenshot below (click for full size):

Subversion commit message being edited

The script itself is relatively simple (it was knocked up quickly; I’ll probably improve on it sometime):

# Do an svn commit, with diffs included in the commit message
svncommit() {

    # Start preparing the commit message which we'll then edit
    COMMITMSG=/tmp/$USER-commitmsg
    echo > $COMMITMSG
    echo "--This line, and those below, will be ignored--" >> $COMMITMSG
    svn status "$@" >> $COMMITMSG
    echo >> $COMMITMSG

    # Now do a diff; work out stats on lines added/removed by looking at
    # the diff, add that info, then the diff itself
    svn diff "$@"   > /tmp/$USER-svndiff
    LINESADDED=$(  grep '^+[^+]' /tmp/$USER-svndiff | wc -l)
    LINESREMOVED=$(grep '^-[^-]' /tmp/$USER-svndiff | wc -l)
    echo "Added $LINESADDED lines, removed $LINESREMOVED lines" >> $COMMITMSG
    echo >> $COMMITMSG
    cat /tmp/$USER-svndiff >> $COMMITMSG
    echo >> $COMMITMSG

    ORIGMD5=$(md5sum $COMMITMSG)
    $VISUAL $COMMITMSG

    if [[ "$(md5sum $COMMITMSG)" == "$ORIGMD5" ]]; then
        echo "Commit message unchanged, commit aborted";
    else
        svn commit "$@" -F $COMMITMSG
    fi

    rm $COMMITMSG
    rm /tmp/$USER-svndiff
}

Synaptics touchpad under Xorg lives again

I have a Dell Inspiron 1501 laptop running Arch Linux, and recently, after an update, the Synaptics touchpad stopped working.

The touchpad shows up in dmesg as:

Synaptics Touchpad, model: 1, fw: 6.3, id: 0x180b1, caps: 0xa04713/0x200000
input: SynPS/2 Synaptics TouchPad as /class/input/input7

I was using a USB mouse until I found time to get the touchpad working again. Here’s what I had to do…

Continue reading Synaptics touchpad under Xorg lives again

Retagging audio tracks based on filename

I had some audio tracks which weren’t tagged, but did have filenames containing the artist, title etc, so I whipped up a quick Perl script to sort them out – retag-by-filename.pl.

It takes a regular expression with named captures for track, title, artist and comment, and sets the tgs on the file as appropriate.

It makes use of Music::Tag to do the actual tagging and Getopt::Lucid to read the options supplied, and requires Perl 5.10.0 for named regex captures (and ‘say’).

A --dry-run option allows you to check that the filenames are being parsed correctly by your regex before actually writing tags.

See retag-by-filename.pl for the full details.

Easy CLI option parsing with Getopt::Lucid

I often write Perl scripts which need to read options given on the command line. Normally I turn to the venerable old Getopt::Long which does the job.

However, I was writing a script which needed to be able to accept only certain parameters, which were mostly optional, and also take a list of filenames. I wanted this to be possible in any order, e.g.:

myscript --foo=foo --bar=bar file1 file2
myscript file1 file --foo foo

Getopt::Lucid makes this all pretty easy, and also makes the code pretty self-documenting, too. Straight from the documentation, showing the various types of parameters it can parse:

@specs = (
    Switch("version|V"),
    Counter("verbose|v"),
    Param("config|C"),
    List("lib|l|I"),
    Keypair("define"),
    Switch("help|h"),
);

$opt = Getopt::Lucid->getopt( \@specs );

$verbosity = $opt->get_verbose;
@libs = $opt->get_lib;
%defs = $opt->get_define;

A real-world example,from one of my scripts which handles ID3-tagging:

# The options we can take - these correspond to the name of the tag that
# they'll set:
my @options = qw(track title artist album comment);

my @option_specs = (
    Getopt::Lucid::Switch('verbose|v'),
    map { Getopt::Lucid::Param($_) } @options,
);
my $opt = Getopt::Lucid->getopt(\@option_specs);

my @tags_to_set = grep { $opt->{seen}{$_} } @options;
my @files = @{ $opt->{target} };

if (!@tags_to_set) {
    say "Nothing to do.  Use one or more of the options:\n" .
        join ', ', map {'--'.$_} @options;
    exit;
}

(The script then goes on to loop over all files, and use Music::Tag to set the ID3 tags requested).

Easy file finding with File::Find::Rule

Recently I found File::Find::Rule on the CPAN, and I’m impressed how easy it makes it to get a list of files to work on.

A fairly common way to do this in Perl would be something like:

my $dirh = new DirHandle($somedir);
while (my $entry = $dirh->read) {
    # Skip hidden files and directories:
    next if ($entry =~ /^\./ || !-f $entry);

    # Skip if it doesn't match the name we want:
    next if ($entry !~ /\.txt$/);

    print "Found: $somedir/$entry\n";
}

File::Find::Rule makes things rather easier:

my @files = File::Find::Rule->file()->name('*.txt')->in($somedir);

Various conditions can be chained together to find exactly what you want.

Another example, showing combining rules with ->any() to find files matching any of those conditions:

# find avis, movs, things over 200M and empty files
my @files = File::Find::Rule->any(
    File::Find::Rule->name( '*.avi', '*.mov' ),
    File::Find::Rule->size( '>200M' ),
    File::Find::Rule->file->empty,
)->in('/home');

There’s plenty of other ways to do this, but I think File::Find::Rule gives a way to clearly and concisely state what you want and get the job done.