Displaying articles with tag

DNS for bash

Posted by hank, Sun Mar 30 21:16:00 UTC 2008

Today, I decided I wanted a network service that propagated variables and aliases to every login shell that subscribed to it. This is dangerous on a large scale, but perfectly acceptable on my small home network where everyone trusts everyone else.

First, I got Camping installed, bringing back fond memories of Ruby development. I then copied off the blog example, and created TreeHugger, a 427 line script that provides a web interface to edit the variables, and a plain text output for the shells to source.

This script, when run, allows some simple MVC actions to an sqlite3 database.

Example Screenshot

As you can see, I have some aliases here I want to send to all the subscribing hosts. Eventually, I want to add some detection functionality to the database (mostly reverse DNS lookups for host rule referencing). I just have to access /out to get my desired output:


# Treehugger Configuration
# Aliases
alias ai='sudo apt-get install'
alias aup='sudo apt-get update'
alias aug='sudo apt-get upgrade'

# Environment Variables

Now, to get this into bash. I looked into making the date command spit out pretty unique timestamps. Turns out you can do this with the nanoseconds format:


$ date +%s%N
1206926780157462141

I made it so wget saves the treehugger config to a tempfile using the somewhat random seed above as a filename suffix, and then I have my shell source it:


FILENAME=/tmp/treehugger-`date +%s%N`; 2>/dev/null wget -O $FILENAME  http://rofl.who/treehugger/out && source $FILENAME && rm $FILENAME

And now I have nice aliases on my laptop served up from my desktop as fresh as the shell:


hank@davros:~$ alias
alias ai='sudo apt-get install'
alias aug='sudo apt-get upgrade'
alias aup='sudo apt-get update'
alias ls='ls --color=auto'

Tags:

Calculating Averages from a CSV with Perl

Posted by hank, Sat Dec 08 13:09:00 UTC 2007

Code

Here’s a quick one-liner using some UNIX utilities and Perl to construct some nice averages from CSV data:


for i in `seq 2 20`; do cat crim_rate_2005_by_state.csv | cut -d , -f $i | perl -e '$c=$d=0;$e;while(<>){if(/^\d/){$c+=$_;$d+=1}else{s/\s{2,}/ /g;s/"//g;chomp($e=$_);}} print $e, ": ", $c/$d, "\n"'; done

And now, the spaced out version:


#!/bin/bash
for i in `seq 2 20`; do 
  cat crim_rate_2005_by_state.csv | \
  cut -d , -f $i | \
  perl -e '$c=$d=0;
    $e;
    while(<>){
      if(/^\d/){
        $c+=$_;
        $d+=1
      } else {
        s/\s{2,}/ /g;
        s/"//g;
        chomp($e=$_);
      }
    } 
    print $e, ": ", $c/$d, "\n"'; 
done

Output

  • Population: 5775431.88461538
  • Violent crime rate: 418.930769230769
  • Murder/manslaughter rate: 5.59038461538462
  • Forcible rape rate: 33.1634615384615
  • Robbery rate: 114.455769230769
  • Assault rate: 265.728846153846
  • Property crime rate: 3339.50961538462
  • Burglary rate: 685.671153846154
  • Larceny/theft rate: 2273.43269230769
  • Motor vehicle theft rate: 380.417307692308
  • Violent crime: 26928.3461538462
  • Murder and nonnegligent manslaughter: 335.730769230769
  • Forcible rape: 1809.67307692308
  • Robbery: 8128.30769230769
  • Aggravated assault: 16654.6346153846
  • Property crime: 196569.711538462
  • Burglary: 41756.0961538462
  • Larceny-theft: 130880.442307692
  • Motor vehicle theft: 23933.1730769231

So, now we have our averages. More work to be done. The data file used is available here:

crim_rate_2005_by_state.csv

Tags:

Linux command line tips and tricks

Posted by hank, Thu Jul 19 22:45:00 UTC 2007

This awesome page told me about the <<< operator in bash. It rocks. It also told me the best way to set an initial login password:


umask u=rw,go=
openssl rand -base64 6 | tee -a PasswordFile | passwd –stdin joe
chage -d 0 joe

Also, there’s ssh-copy-id:


Usage: /usr/bin/ssh-copy-id [-i [identity_file]] [user@]machine

Tags:

GNU Screen's hardstatus

Posted by hank, Sat Jul 14 20:17:00 UTC 2007

I use GNU Screen. A lot. I found an article linked from DIgg today that showed me how to use a setting called hardstatus to set the little bar at the bottom to my liking. I decided to mess around with it a bit, and I ended up with this:

Such a hard status!

It shows my hostname, IP, uptime, screen window number and name, date and time, and load averages. Pretty cool, huh?

This is how you do it:

  • First, create a .screenrc file and dump this in there:

hardstatus alwayslastline
backtick 1 60 60 /home/hank/.screen_hardstatus
hardstatus string "%{Gk}%H: %{+s y}%1` | %=%n: %t%= | %m/%d %c | %{+b}%l"
  • Now, see the line that starts with backtick? That tells screen what program to run for assigning output to %1` in the hardstatus string. Let’s make the .screen_hardstatus file as well (make it in your own home directory).

#!/bin/bash
# Script to get run by hardstatus in screen.
# Prints customized single-line system stats
IP=`ifconfig eth0 | grep Mask | cut -d: -f2 | cut -d " " -f1`
UPTIME=`perl -pe 's/^(\d+).*/sprintf("%d", ($1\/(24*3600)))." days"/e' /proc/uptime`
echo -n "$IP | Up: $UPTIME"

I cheated and used perl, but all of this could safely be converted to sed/awk easily. All this does is print my raw dotted quad IP address, a pipe, and then the current uptime in days rounded down.

  • Now, just run screen. You should see something similar to the first picture. I used this page a lot to customize the colors, etc.

Tags:

Using seq to zero-pad strings in a series

Posted by hank, Sat May 19 04:06:00 UTC 2007

I thought this was pretty cool:

for i in `seq -f "%03g" 1 100`; do wget http://www.gozerog.com/images/Hawking_$i.jpg; done

We were trying to do this the other night using bash, but to no avail since the square brackets only work for local file path expansion. I should have remembered seq. Also, this example shows how to 0-pad a series using seq and bash, noted by the *-f* option. Three cheers for seq!

Tags:

Not a sandwich, but a Vim Which!

Posted by hank, Mon Mar 26 14:40:00 UTC 2007

I often find myself going to find scripts I’ve written that I want to edit, but I decided today I’d make things easier on myself:


hank@rura-penthe ~ $ cat bin/vimwhich 
#!/bin/bash
vim `which $1`

All this does is shorten vim `which myscript` to vimwhich myscript. Helpful for just a couple lines of code.

Tags: