Friday, October 28, 2011

A coworker of mine was asking me one of his favorite interview questions.  It basically goes like this:

"Write me something that will change any file ending in .html to .htm"

Okay, simple enough, I write out a quick bash loop and hand it to him, then he says:

"Okay, now let's say the directory has spaces in the name"

A bash for loop will create an array by splitting on spaces, so something like this would break:

for file in `find ./ -name *.html`
do
  mv $file $newfile
done

If you had a directory named "my directory" you'd have an entry for "my" and an entry for "directory/blah.html" which wouldn't work.

The solution is to do some "while reading this line" bullshit in bash, but my solution was much more elegant, throw away bash and use ruby:

irb(main):001:0> Dir.glob("**/*.html").each do |fileName| system( "mv \"%s\" \"%s\"" % [fileName,fileName.gsub( /\.(html)$/,".htm" )] ) end

This question is designed to see if you can think around complicated scenarios.  However, in the wild I'd never trust bash to do the right thing.

Bash is dumb, ruby is elegant perfection.  I guess I would have failed that interview question. ;)

Tuesday, October 25, 2011

Chef is fun.

I'm currently using chef to manage 91 nodes, and find it to be a fantastic tool. I esspecially like to combine knife commands with shell stuff for something like this:
for node in `knife search node "chef_environment:prod"|grep "Node Name"|awk '{print $3}'`; do         echo -ne "${node}\t" ; knife node show $node -a ec2.instance_type; done |awk '{print $1 "\t" $3}'
Which gives me a list of nodes in production along with their ec2 instance type.  It's handy for generating simple reports, and getting an idea for how may instances of each type we have running in any given environment.