Shell Scripts
On my computer, I live in Bash. Over the few years I've been living in here, I've devised a few simple scripts, in Bash and Perl and Python, that I actually use fairly often. These are a few of those.
ref
I connect to a handful of different servers, in a bunch of different ways. It gets annoying to type out the same username@hostname strings over and over, so I devised the following Perl script to keep aliases for me. it reads an alias file named .ssh-alias, tries to find the line that starts with the given alias, and, when found, prints it. Pretty simple stuff.
#!/usr/bin/perl # A nifty little thing that reads an alias file (in the home directory) # before calling ssh.
$home = $ENV{HOME}; die "Need an argument to lookup in table.\n(\$\#ARGV == $#ARGV)\n" unless $#ARGV == 0; open(ALIASES, "$home/.ssh-alias") or die "Couldn't open $home/.ssh-alias";
$key = $ARGV[0];
while(<ALIASES>) { next unless /(\w+): (\S+)/ and $1 eq $key; close ALIASES; print "$2\n"; exit 0; }
die "Didn't find $key in $home/.ssh-alias";
Each line of the alias file is in the format <alias>: <user@host>. The aliases are much shorter than the user/hostname pair, so this is pretty nice. For example, I can type `ref wisc` instead of elder@baptista.cs.wisc.edu - with the backticks, they evaluate to the same thing.
But the way I wind up using this script the most is in other scripts. For example, I've a script messh, which essentially takes the input $alias and executes the command ssh `ref $alias`, modulo argument-passing and error-trapping.
mnt and umnt
This script, in straight-up bash, makes it easy for me to use the quite awesome sshfs, which lets me mount remote directories on machines to which I have ssh access as if they were on my local filesystem. However, it can be an inconvenient pain to remember the actual incantations to do this mounting.
mnt, with ref, makes this unnecessary. It's this:
cd url=`ref $1` mkdir -p $1 sshfs ${url}: $1
Its inverse, umnt, is this:
cd fusermount -u $1 rmdir $1
So, to mount my Wisconsin CS account's home directory, I type mnt wisc. To unmount my Wisconsin CS account's home directory, I do umnt wisc. It's very nice. In fact, I'm writing this on my home computer, with my tehposse.org home directory mounted under posse.
note
I'm inordinately proud of this one. A while back, when I'd first built FiddleType, I wanted to build a teeny-tiny, Unixy, blog-thing. That's where Notes comes from. To write each entry, I run note. note builds the formatted date, opens up vim, and then prepends the resulting text to the beginning of the Notes page. This is really all I need from a blogging system, plus it lets me use the full-featured editor that I'm already accustomed to instead of making me write things in the web browser - or, more likely, cut and paste out of vim.
Frankly, note exists because I found out that ssh can pipe arbitrary data to arbitrary remote programs, and I wanted to come up with an excuse to do so.
echo == `ddate +'%{%A, %d %B%} %Y'` > newNote; echo " " >> newNote; vim newNote echo " " >> newNote;
cat newNote | ssh user@hostname.com ' cd matt/pages; cat - >> newNote; cat Notes >> newNote; mv newNote Notes; ' rm newNote
photo-name
The following script runs through a directory of images, showing me each image and prompting me to rename them. I use this to organize pictures that I upload from my camera.
#!/usr/bin/perl -w use strict; die "photo-name <filename>\n" unless $ARGV[0]; foreach my $filename (@ARGV) { die "$filename not found\n" unless stat $filename; # Open image with an xview process. my $kid = fork(); my $stem, my $tail; exec("xview -shrink -q $filename") unless $kid; # Get user's new file name. if($filename =~ /(.*)\.([^.]*)/) { $stem = $1; $tail = ".$2"; } else { $stem = $filename; $tail = ""; } print("Rename $stem to: "); my $input = <STDIN>; $input =~ s/\n//; # Close xview process. kill "SIGKILL", $kid; $input .= $tail; # Move file, if input given. system("mv $filename $input") if $input ne $tail; }
xyzzy
And one last one, named xyzzy:
#!/bin/bash echo Nothing happens.