Archive for the ‘work’ Category
My tech-mojo has gone on vacation.
… and with it, took my Xbox 360 and my laptop.
More or less my Xbox has decided to start red ringing and working intermittently – it will soon be shipped back to Microsoft in a coffin if it doesn’t straighten its act out.
Last night I tried to install my shiny new copy of Leopard retail, only to discover that my Macbook dvd drive refuses to read dvd’s 19 out of 20 times. I really don’t want to bring that to the Apple store, because it will definitely result in my trusty Macbook being shipped to Apple for repair – which could take awhile.
In the mean time I will just have to live vicariously through upgrading other laptops to Leopard.
Quick Rant
I HATE it when people use the urinal in the mens lavatory and feel its okay to leave without washing their hands. I mean, come on people! I takes 15 seconds to wash your hands, and another 15 seconds to dry them. Heck, Thomson is even paying for you to wash your hands – for the sake of everyone else that has to touch the door handle to leave the lavatory Please wash your hands!
Remotely executing shell commands in a bash script with ssh and expect
So an on going project of mine at work had been to create a bash shell script, that could be run at regular intervals, that would check that all servers in an environment were identical compared to their “master server”.
This would require comparing each server against its master with a specific set of criteria:
- Network Filesystem Mounts
- User accounts
- Groups
- Group ID’s and User IDs
My approach was simple, for each criteria use a set of commands to retrieve the necessary information, and save it to a text file in a sorted manner. Then compare that against a file generated in the same manner for the master server in that environment.
This is all fine and peachy, until you actually want to send these commands to several servers spread out across a network, without the need for human interaction.
The method of sending commands and retrieving their output was an SSH connection to each machine, but unfortunately you can’t send your SSH password on the command line. So to fix this hurdle, I used the expect binary, which basically watched standard output for a string, and sends your response.
Searches on the interwebs came up with sparse results on this matter, so below is my contribution so that hopefully a fellow geek won’t have as much non-luck as I with Google.
linux_ssh.expect
###
# 2007 – Nicholas Pike
#
# This script takes 4 parameters, and will execute a command (or set of commands) on a remote server.
# hostname
# password
# username
# command
#
###
set hostname [lindex $argv 0]
set password [lindex $argv 1]
set username [lindex $argv 2]
set command [lindex $argv 3]
spawn ssh $username@$hostname $command
expect “password: ”
send “$password\r”
send — “\r”
expect eof
From within a bash script, you can call this file with the expect binary like so:
# runRemoteCommand takes 3 parameters (See below). This will run a command (or series of commands) on
# all machines listed in $BOX_LIST for the current environment specified in run()
# The output of these commands will be written to a file located:
# box_compare/commandLabel/environment/[nameofserver]
# After the polling is complete, the output files of the slave servers are diff’d against the
# master servers output.
# The results are appended to the text report for this environment.
#
# runRemoteCommand “helloWorld” “Hello World” “echo \”hello world\”; ls”
#
# first parameter is command label
# second parameter is criteria name
# third parameter is command
#
runRemoteCommand() {
mkdir $PATH_COMPARE/temp/$1
mkdir $PATH_COMPARE/temp/$1/$ENVIRONMENT
COMMAND=$3
# run the remtoe command for each server in the box list for this environment
for server in `echo $BOX_LIST`
do
EXPECT_COMMAND=”"$COMMAND”"
expect -f linux_ssh.exp $server $PASSWORD $USERNAME “$EXPECT_COMMAND” > $PATH_COMPARE/temp/$1/$ENVIRONMENT/$server
done
}
The important line of course being:
Ta-da!
So there ya go, a quick and “easy” way to send shell commands via SSH in a bash script to other *nix based computers.