2008-06-20

Part of the reason I prefer to work in linux

One of the most common complaints that I've heard from people about really learning their way around linux is that they don't like having to remember long cryptic command-line arguments. Granted, these days you can get by decently well without using the shell, but then again, things in the linux world are not always too well polished, there's a decent amount of variation between distros, etc.

One thing that's almost constant is the presence of BASH, and everything being able to be launched from a shell. Most things also print useful information to the shell, and you can use this to your advantage.

Here's a situation that I was recently in:

I'm doing development on two projects right now, the extendible-tetris thing, and a site for the art-collectiveish house I live in. The extendible-tetris thing has only been going on in the background, since I've been focusing on the site for the house (we make a lot of music and art,
want to put it online freely available and have a simple paypal donate/buy and get a nice DIY made CD/DVD combo, or some other art for cheap). Now for this house site, I have a tower running ubuntu server that's connected to a wireless router that has no access to the internet - it won't be viewable online until the first iteration of it is ready to go, and the other people in the house can use the development version and provide feedback, etc.

We also have an internet connection with it's own wireless network. Occasionally, I need to install something on the server, and I need to download some source packages, switch to the private network, upload them, ssh into it and compile / install. Sometimes I run into an unmet dependency (I was pretty thorough setting the server up, but you can't catch everything), and I need to do this multiple times. When I'm working on stuff, I'm mostly in emacs and the shell, and don't want to take my hands off the keyboard very often. There's a repetitive task, and I don't want to move my mouse to switch networks then sit and wait over and over. I also don't want to type out the iwconfig commands anymore than I have to.

So, I have this well-defined task that needs to be done many times - make sure I'm on the right network, upload a file to a server, then ssh into that server. Using the tools provided to me by BASH, I can turn this from myself performing many small commands manually, to myself performing one command manually that does all the rest for me:

[disclaimer: I am far from being a BASH-scripting guru. There are probably things that I should be doing differently. Feel free to point them out.]

First, I make a small script to report back the name of the wireless network I'm currently on:


#!/usr/bin/env bash

#wwhich - print out which wireless network we're currently connected to
iwconfig 2>/dev/null | sed -n -e 's/.*ESSID:"\([^"]*\)".*/\1/p'


That's a little nasty, but it works.

Next, we have a script to switch between two wireless networks:


#!/usr/bin/env bash

#wswitch - switch between two wireless networks.

#which essids we're dealing with
first="wnetwork1"
second="wnetwork2"


current=`wwhich`


if [ $first == $current ]
then
sudo iwconfig wlan0 essid $second
current=$second
else
sudo iwconfig wlan0 essid $first
current=$first
fi

#print out the current network
echo "$current"


This is not a general-solution script - it's for this specific problem. If I run into something like this again (where I need to be switching between two wireless networks), I can just change the names of the variables.

Next, we have the upload and ssh script:

#!/usr/bin/env bash

target="essid-name"
current=`wwich`
user="auser"
host="192.168.x.x"
dest=":~/incoming"

#make sure we're on the right wireless channel
if [ $target != $current ]
then
wswitch
fi

#make sure we call the right scp command
if [ -d $1 ]
then flag="-r"
else flag=""
fi
scp $flag $1 $user@$host$dest
ssh $user@$host


This will only work if you have ssh set up to use public keys. Which you probably do.

Now, if we can ignore my probably pretty shoddy bash-scripting skills, we get to the more major point: A task that previously took around 30 seconds - plus the time to upload - each time I needed to do it now takes around one second, plus the time to upload. You can write all kinds of time saving utilities for yourself, put them in a directory, and add that directory to your $PATH in ~/.profile. This is a large part of the reason why people like me like the shell so much, and prefer working in linux, or a unix-like environment - if I don't want to, I don't have to waste my time with repetitive tasks. I can automate them. If I felt like it, I could bind this to a keystroke.

Don't like having to remember strings of commands? Throw them in a script. You have the capability to automate just about anything on your system, so do it. Don't like having to remember certain paths? Export them into a variable in your ~/.profile. Et cetera.

With a powerful shell, in combination with good utilities, I can turn the tools that I use to accomplish things into more powerful, more general, or task-specific tools. It took me around 20 minutes to write the above scripts - and it probably only took me that long because I'm not extremely familiar with BASH-scripting, although I have recently started writing many more scripts. It will probably save me more than 20 minutes of time over the course of the next few weeks.