Archive for the ‘Technology’ Category

SSH Without Password

Tuesday, May 18th, 2010

I was looking for a quick and dirty way to SSH into a handful of hosts. I SSH into these hosts all day long, and I was looking for a way to skip the password prompt (I’m way too much into efficiency — every second counts!). I wasn’t interested in learning how to set up the public/private key authentication. I just wanted to automate the login so all I would need to type is goto host. Obviously this is less than secure, but I’m not overly concerned with security at my workstation.

Here’s what I came up with:

1) a file named goto.passwd
– which contains hostnames, usernames, and passwords (e.g. myhost myuser mypassword)
2) a script named goto
– which accepts one parameter (e.g. goto myhost)
– parses the goto.passwd file looking for that host
– and then passes that info to
3) a script borrowed from here
– and slightly modified.

Here is an example (the command is simply goto myhost and I’m instantly in.):

john@jslinux:~> goto myhost
spawn ssh user@myhost
user@myhost’s password:
Last login: Tue May 18 11:31:05 2010 from 1.2.3.4
-bash-3.2$

Here are the scripts (you can also download them as a zip or tar):

goto.passwd

myhost root password
myotherhost root passwordforroot
anotherhost root password12345

goto

#!/bin/bash
host=$1
user=`cat goto.passwd | grep -e ^$host | awk '{print $2}'`
pass=`cat goto.passwd | grep -e ^$host | awk '{print $3}'`
goto.expect $user $pass $host

goto.expect

omitted. see zip or tar file below.


goto.tar
goto.zip

Viewing very large log files

Thursday, April 15th, 2010

Someone came to me today and asked if I could track down a 403 error that was handed to a user the morning of 4/13/2010. The web server log file is 465 megs. Gulp. sed and grep to the rescue!

Just pick a random number (representing a wild guess at where, in the log file, your starting point may be) and use sed -n 2000p where 2000 is your random number. My original guess was way off. The time period in question ended up spanning lines 500,000 to 680,000 in the server log. Great, just read 180,000 lines, right? WRONG! Use grep. Here’s the final string of commands I used.

# just to locate the correct line...
sed -n 2000p site-access_log
sed -n 12000p site-access_log
sed -n 100000p site-access_log
sed -n 300000p site-access_log
sed -n 500000p site-access_log
sed -n 680000p site-access_log

# now to search that time period for a 403 error
sed -n 500000,685000p site-access_log | grep ' 403'

Not perfect, but good enough to get the job done. sed whittled the 465 meg file down to 180,000 lines, and grep whittled that down to 50 or so lines, some of which were relevant, others not.

Convert Inches to Feet and Inches

Wednesday, January 6th, 2010

I love simple problems, such as fill a drop-down with a range of feet and inches.

One way to do it is to hand-code a <select> element and fill it with hand-coded <option> elements, but what’s the fun in that?

It’s more fun to iterate over an array (range) of integers representing inches, and do the math to convert those inches to feet and inches. To get feet, use the floor function, which truncates all decimal places without rounding. To get inches, use the modulus operator (the % operator) which returns the remainder. 36 is 3′0″ and 74 is 6′2″.

The math is the same but (as John Madden would say, if he were a programmer) the syntax varies by language… Here’s how you do it in Ruby:

<%= select :person,
       :height,
       (36..95).collect{|i|["#{(i/12).floor}' #{i%12}\"",i]},
       {:selected=>@person.height} %>

And here’s what you end up with:

And unformatted:

select :person, :height, (36..95).collect{|i|["#{(i/12).floor}' #{i%12}\"",i]}, {:selected=>@person.height}

Loop, svn log, awk, cat, egrep echo Example

Tuesday, January 5th, 2010

So, I just checked in some files and I realized “doh! I didn’t check to see if there’s any debug trash in there!” My debug trash is fairly easy to detect: I only use raise or puts in Ruby and alert in JavaScript for basic “hello world” type things when debugging some particular issue.

Trouble is, sometimes I forget to remove that trash code before checking it in. To prevent big problems, I refrain from using the Ruby raise command and instead use puts which is fairly harmless. Anyway, I wrote a script to 1) ask SVN for the list of files modified by my checkin and 2) use awk to figure out the file names and, within a loop, 3) use cat to pass the contents of each file to 4) grep / egrep to look for alert, raise, and/or puts statements within the files. So now I have an example of a handful of common Linux commands that I can post here for future reference.

for l in `svn log -r 298 -v | egrep M | awk '{print $2}'`;
do
echo ${l};
cat .${l} |
egrep 'alert|puts|raise';
done

Which spat out:


/app/models/some_model.rb
/app/models/some_other_model.rb
/app/models/foo_model.rb
/app/controllers/home_controller.rb
    puts "hello world"
/app/controllers/foo_controller.rb
    #puts "hello world"
/app/controllers/other_controller.rb
    puts "hello world" unless some_condition

And I found three instances of debug trash… One commented out, one from a previous check-in, and one that I need to remove!

And on one line, without formatting:

for l in `svn log -r 298 -v | egrep M | awk ’{print $2}’`; do echo ${l};cat .${l} | egrep ’alert|puts|raise’;done

Make FireFox 3 Files Writable In Linux

Tuesday, December 8th, 2009

This is something that really pisses me off: FireFox 3 makes downloaded files read-only because they’re saved in /tmp, and OpenOffice doesn’t let you manipulate a read-only file. Even for something stupid and simple, like changing page margins, you have to click the pencil icon in the toolbar, click OK to an error message, and click Yes to something else. FF says “it’s supposed to be read-only, have OO fix it” and OO says “it’s read-only, tell FF to make it not read-only” and lowly-user daresay “M$ Turd handles this gracefully” and “Hey, FF, if you had made this a user-configurable option in FF3 instead of doing a global search & replace, this wouldn’t be an issue!”

Well to hell with it. This script fixes the problem by watching /tmp for files ending in doc,csv,xls,odf (and some others) and makes them writable by using the inotifywait command, which is part of the inotify-tools package. I use openSUSE so it was easy to find in the Install Software applet.

I was going to make an init.d script out of it, but I am busy… It’s just running in a Konsole on Desktop 4 along with all the other out-of-the-way stuff.

#!/bin/bash

# author John Stanfield
# makes files in /tmp/ writable upon creation
# this is a workaround for the religious war between OpenOffice and Mozilla regarding read-only files
# it's intended for users who want to
#  1) download a file
#  2) make a small edit (e.g. page margin, white space, etc)
#  3) read it, print it, email it, etc
#  4) IMPORTANT!
#     a) not be upset if the file is, accidentally or otherwise, deleted in the future
#     or
#     b) save the file elsewhere

inotifywait -m -e create --format %w%f /tmp/ | while read line
do
  if (echo found file... ${line} | egrep "\.od[t|s|p|g|f]$|\.csv$|\.doc$|\.rtf$|\.xls$|\.ppt$"); then
    chmod +w "${line}"
    echo `date` made ${line} writable
  fi
done

And unhighlighted:

#!/bin/bash

# author John Stanfield
# makes files in /tmp/ writable upon creation
# this is a workaround for the religious war between OpenOffice and Mozilla regarding read-only files
# it's intended for users who want to
#  1) download a file
#  2) make a small edit (e.g. page margin, white space, etc)
#  3) read it, print it, email it, etc
#  4) IMPORTANT!
#     a) not be upset if the file is, accidentally or otherwise, deleted in the future
#     or
#     b) save the file elsewhere

inotifywait -m -e create --format %w%f /tmp/ | while read line
do
  if (echo found file... ${line} | egrep "\.od[t|s|p|g|f]$|\.csv$|\.doc$|\.rtf$|\.xls$|\.ppt$"); then
    chmod +w "${line}"
    echo `date` made ${line} writable
  fi
done

Linux Command to Open Multiple Files

Thursday, November 5th, 2009

UPDATE: I like vi more than Aptana now. Here’s how I use svn up to update a bunch of Rails sites, and then use vi to edit a file in each site:

for l in `ls -1`; do
  svn up ${l}/config/environment.rb;
  vi ${l}/config/environment.rb;
done

And when I’m done with my changes, I commit them all at once (sort of) with the same message:

for l in `ls -1`; do
  svn status -q ${l}/config/environment.rb |
    egrep '^M' |
      svn commit `awk '{print $2}'` -m "changed environment.rb";
done

One lovely thing about Ruby on Rails is the uniformity of the directory structure. All of my apps have pretty much the same files in pretty much the same folders. Today, I wanted to edit the environment.rb file in each of my company’s nine applications. Ugh, what a ton of mouse clicks digging through nine directory structures (note: I am very much into efficiency — every second counts, and manual repetitive tasks suck). I thought There’s gotta be a way to find all files named environment.rb and open them in Aptana. This command works! I can get my work done in seconds now instead of minutes! I use locate, which keeps a database of file names… I’ve found it to be faster than find.

The command below will first locate all files beneath the present folder (that’s what $(pwd) does) matching the regular expression /.*environment.rb$/ which means all files ending in environment.rb which will exclude any SVN files with similar names. Files that match that regular expression will be passed to Aptana, which will open any and all files passed in as arguments. Aptana will use an existing window if open, otherwise it will open a new one (precisely what I want!).

aptana $(locate $(pwd)/.*environment.rb$ -r)

It is the same as:

aptana /apps/app1/config/environment.rb /apps/app2/config/environment.rb /apps/app3/environment.rb

It’s much faster than:

aptana /apps/app1/config/environment.rb
aptana /apps/app2/config/environment.rb
aptana /apps/app3/config/environment.rb

And here’s a textarea to tinker, copy, & paste from:

Mount a Windows Share in Linux

Wednesday, November 4th, 2009

I always forget the syntax… Here it is:

su
mkdir -p /mnt/whatever/you/want
mount -t cifs //hostname/sharename -o username=user,password=pass /mnt/whatever/you/want

And without formatting:

su
mkdir -p /mnt/whatever/you/want
mount -t cifs //hostname/sharename -o username=user,password=pass /mnt/whatever/you/want

Linux TCP Window Scaling Problem

Wednesday, October 21st, 2009

The router at my office, a Linksys RV082, doesn’t like Linux computers. Supposedly it doesn’t like Vista or Windows 7 computers either (but what/who doesn’t, anyway?!?!). The problem is TCP window scaling, which (for performance reasons) tinkers with packets in a way that the router does not understand (possibly because the router is running firmware that is older than the concept of TCP window scaling, but firmware upgrades fail so I don’t know if the latest firmware fixes the problem). This command fixes the problem by turning off TCP window scaling.

echo 0 > /proc/sys/net/ipv4/tcp_window_scaling

openSUSE 11.1 + NVidia 9600 GT + Acer AL2216

Friday, October 16th, 2009

Whew… Two years ago I bought two of the Acer budget or economy LCD screens from NewEgg (newegg.com). They’re the 2216 screens that are always nicely priced (mine are AL2216wbd but the last few letters change [my company has purchased several varieties including AL2216WBD and V223WBD -- all are great monitors for typical non-graphic-artist business use]). They worked fine in Windows XP with an ATI FireGL card.

Fast forward to today: I just built a new Linux machine running openSUSE 11.1. The NVidia driver install was simple using “the hard way” described here. But the screens gave me a headache within 30 seconds of looking at them. Text was pixilated and fuzzy, and just about everything was so bright that it had white outlines. It was hard to look at. I thought I installed the driver wrong and it was using the wrong resolution and color combination — but it turns out the settings needed a little tweaking. I tried a bazillion different things, and I even contemplated going back to Windows (OUCH). Finally, I went through the painstaking effort of fiddling with all of NVidia’s settings. I am happy to say that this works:

Step 1: Edit /etc/X11/xorg.conf to add the settings described here in the section that begins with “For nVidia drivers you may have to disable automatic detection of DPI to set it manually.” It says to add these two settings to the Section “Device” section of xorg.conf:

  Option   "UseEdidDpi" "false"
  Option   "DPI" "96 x 96"

Step 2: Use the NVidia X Server Settings applet (just click the Gecko / Application Launcher and type nv in the search box) to adjust the brightness, contrast, and gamma. Those settings are under X Screen 0 -> X Server Color Correction. The brightness, contrast, and gamma settings pictured below worked best for me — the headache has gone away!!!

snapshot1

snapshot1

openSUSE Ruby on Rails Hack

Tuesday, October 13th, 2009

Note: This was my first attempt at using openSUSE. On my second attempt, I no longer had this problem. My guess is that I installed the wrong version of something-or-other which caused this problem.

If you have openSUSE 11.1, like I do, then you have Ruby 1.8.7. I encountered an error when trying to run ruby script/console and ruby script/server for the first time in openSUSE. This pretty much killed everything — most of my plug-ins and models didn’t load.

activesupport-1.4.2/lib/active_support/core_ext/string/access.rb:43:in `first’:NoMethodError: 
undefined method `[]‘ for #<Enumerable::Enumerator:0×7f1e1b77aa20>

The problem is that, in Ruby prior to 1.8.7 (perhaps much prior, I don’t know), the [] and/or first methods on String returned an array of characters. Now that has changed so that they return an Enumerable::Enumerator.

I added a hack to the top of /config/boot.rb so that it’d behave. I’ll figure out the real problem later — I’m busy! I found this example elsewhere, but I chose to but it in boot.rb:

unless '1.9'.respond_to?(:force_encoding)
  puts 'un-defining :chars method on String for ruby 1.8.7 compatibility'
  String.class_eval do
    begin
      remove_method :chars
    rescue NameError
      # OK
    end
  end
end

And unformatted:

unless ’1.9′.respond_to?(:force_encoding)
  puts ’un-defining :chars method on String for ruby 1.8.7 compatibility’
  String.class_eval do
    begin
      remove_method :chars
    rescue NameError
      # OK
    end
  end
end