Archive | ShellScript

Running a BASH script when my Laptop is opened at home ā€“ Part 2

As I mentioned in this post I should be able to run a script to find my current gateway’s MAC address. With this info, I should be able to tell when I am home, and launch a script. In this post, I talk about sleepwatcher, which runs a script when the machine is woken up. Sleepwatcher looks for a file named .wakerc and executes it when the machine wakes. If I put the following in my .wakerc, it will execute whatever I like (for example a rsync script) when the machine is woken up and at home:

 

#!/bin/bash
sleep 120
GATEWAY=`/usr/sbin/netstat -rn | /usr/bin/grep default | /usr/bin/grep en1 | /usr/bin/cut -c20-35`
MACADDRESS=`/usr/sbin/arp -n $GATEWAY | /usr/bin/cut -f4 -d' '`
if [ "$MACADDRESS" = "xx:xx:xx:xx:xx:xx" ]; then
	/bin/echo "$(date): I am at home now: $MACADDRESS" >> ~/Desktop/wake.txt
	# script I want to run at home is next line
	rsync Documents/ server:Documents/
else
	/bin/echo "$(date): I don't know where I am: $GATEWAY $MACADDRESS" >> ~/Desktop/wake.txt
fi

Powershell script to install Cygwin

I like having Cygwin installed on my machine, and since I always re-image, I needed a script to install Cygwin automatically.

function Install-Cygwin {
   param ( $TempCygDir="$env:temp\cygInstall" )
   if(!(Test-Path -Path $TempCygDir -PathType Container))
    {
       $null = New-Item -Type Directory -Path $TempCygDir -Force
    }
   $client = new-object System.Net.WebClient
   $client.DownloadFile("http://cygwin.com/setup.exe", "$TempCygDir\setup.exe" )
   Start-Process -wait -FilePath "$TempCygDir\setup.exe" -ArgumentList "-q -n -l $TempCygDir -s http://mirror.nyi.net/cygwin/ -R c:\Cygwin"
   Start-Process -wait -FilePath "$TempCygDir\setup.exe" -ArgumentList "-q -n -l $TempCygDir -s http://mirror.nyi.net/cygwin/ -R c:\Cygwin -P openssh"
}

This will download and install Cygwin and install the openssh package.

Running a BASH script when my Laptop is opened at home – Part 1

My laptop hard drive died. I was upset only because there was data on my laptop that had not been moved over to my desktop. My desktop has time machine and is rsynced to several other drives and locations.

So I lost data. My own fault because I was not diligent in moving data off my laptop.

To make sure this did not happen again, I needed the ability to run a script when I open my laptop at home. But how?

  • First, I thought about identifying being at home by my wireless SSID. That was okay, but what if I was connected by wire?
  • Second, I thought about identifying home based on my subnet. Well, I could find myself on a network with the same range, and that could be bad.
  • Then I found this link that showed some code on how to get the MAC address of the defined Default Gateway. Perfect.

MAC addresses should be unique. Therefore the BASH script should only run when I am on my home network.

Here is the BASH script to find the Default Gateway’s MAC address

GATEWAY=`netstat -rn | grep default | cut -c20-35`
MACADDRESS=`arp -n $GATEWAY | cut -f4 -d' '`

Next step is to use this code when I open my Laptop lid.

Comparing master and slave MySQL WordPress DBs

My VPS host – Rackspace contacted me the other day to tell me that my host server became unresponsive. After it came back online I went to my MySQL replicated slave to check the status. The /var/log/mysqld.log said:

Error reading packet from server: Client requested master to start replication from impossible position

This article siad

“9 times out of 10 it’s because the master crashed and when it came back online a new binlog file was made”.

That sounds about right, my virtual host was probably force rebooted, and my VM crashed. I recovered my DBs by re-mirroring my DBs over an AutoSSH connection between my two servers.

The article goes on to say:

Now if your super sensitive of lost events because a row or two could of been lost from this replication event, do some spot testing for tables written to often”

I wanted to verify my DBs were the same on both master and slave, so I wrote this BASH function:

function CompareDBs {
if [ $1 ]; then
DB=$1;
RDBDUMP=$(mysqldump -h <a href="tel:127.0.0.1">127.0.0.1</a> -P 7777 --order-by-primary --skip-extended-insert --skip-opt --skip-comments $DB)
LDBDUMP=$(mysqldump --order-by-primary --skip-extended-insert --skip-opt --skip-comments $DB)
diff -y --suppress-common-lines &lt;(echo &quot;$RDBDUMP&quot;) &lt;(echo &quot;$LDBDUMP&quot;)
fi
}

Call the function with the DB you want to compare. This script assumes that you have an SSH Tunnel between your two servers.

 

********* MAKE SURE YOUR TIME IS RIGHT ON BOTH SERVERS*********
This will save you some hair pulling!

Drop all MySQL DBs (except mysql & information_schema)

For some reason I can not remember the following command. I have been using it a lot lately when testing MySQL replication.

  1. mysql –skip-column-names –batch -e “show databases” | grep -E -v “mysql|information_schema” | xargs -I “@@” mysql -e “drop database @@”

This will drop all DBs except the default mysql and information_schema dbs. Then I can Rinse and Repeat this script. Of course only do this on the slave!

Script to compare RPMs on two different CentOS servers

I wanted to make sure that the same RPMs were installed on several servers. I wasn’t worried about versions of RPMs because everything should be kept up to date via yum. So I sat down and wrote the script below. It has been on my ToDo list for quite a while!

RRPM=$(ssh $REMOTESERVER "rpm -qa --queryformat '%{NAME}\n'" )
LRPM=$(rpm -qa --queryformat '%{NAME}\n')

echo "*** Missing from $REMOTESERVER" ***
grep -vf <(echo "$RRPM"| sort) <(echo "$LRPM"|sort)
echo
echo "*** Missing from Local system ***"
grep -vf <(echo "$LRPM"| sort) <(echo "$RRPM"|sort)
echo

This script connects to a remote machine and compares RPMs installed there to the RPMs that are installed locally.

AutoSSH on CentOS

I have been interested in MySQL replication over ssh and I wanted a way to make sure that the tunnel is always up. Everyone says to use AutoSSH. AutoSSH is not in EPEL, but is in rpmforge (Is that that same as DAG? Didn’t they merge?). I installed rpmforge:

rpm -Uhv http://apt.sw.be/redhat/el5/en/i386/rpmforge/RPMS/rpmforge-release-0.3.6-1.el5.rf.i386.rpm

I don’t like to do the RepoDance, so I disabled rpmforge:

sed -iĀ "s/enabled = 1/enabled = 0/" /etc/yum.repos.d/rpmforge.repo

Next I installed AutoSSH

yum install --enablerepo=rpmforge autossh</p>

And finally my Bash function to create an AutoSSH tunnel:
 

function StartAutoSSH {
	. /etc/rc.d/init.d/functions
	AUTOSSH_PIDFILE=/var/run/autossh.pid # we are assuming only one autossh tunnel
	if [ ! -e $AUTOSSH_PIDFILE ]; then
	AUTOSSH_PIDFILE=$AUTOSSH_PIDFILE;export AUTOSSH_PIDFILE
	autossh -M29001 -f -N -L7777:127.0.0.1:3306 [email protected]
	else
	status -p $AUTOSSH_PIDFILE autossh
	fi
}

If you call this function, it will created the specified tunnel or if it is up and runnng, then it will spit back the PID.

Mirror all MySQL DBs to the local machine

Continuing on my quest to get MySQL replicating over ssh, I am using the following bash function to replicate all remote DBs locally:

 

function MirrorAllRemoteDBsToLocal {
	for REMOTEDB in $(mysql -h 127.0.0.1 -P 7777 --batch --skip-column-names -e "SHOW DATABASES")
	do
	LOCALDBEXISTS=$(mysql --batch --skip-column-names -e "SHOW DATABASES LIKE '"$REMOTEDB"';" | grep "$REMOTEDB" > /dev/null; echo "$?")
	if [ $LOCALDBEXISTS -ne 0 ];then
		echo "adding $REMOTEDB to local MySQL"
		mysql -e "create database $REMOTEDB;"
		echo "getting a dump"
		mysqldump -h 127.0.0.1 -P 7777 $REMOTEDB | mysql $REMOTEDB;
		echo " adding $REMOTEDB to my.conf"
		sed -i '/master-port/a\\treplicate-do-db='$REMOTEDB'' /etc/my.cnf
	fi
	done
}

Line 2 connects to the local AutoSSH tunnel and gets a list of all the remote DBs.

Then we loop through the DBs and if there is not a DB locally with that name, the script will create a database. Next the script gets (Line 9) a dump of the DB and copies it to the newly created DB.

And finally the script add the DB to the /etc/my.cnf (line 11).

All that should have to happen is to issue a slave stop and then slave start, and all DBs should be mirrored locally.

OS X: Move files based on creation date

I wanted to organize my flip videos – I wanted them moved into a folder named after their creation date.

One of the scripts that I found uses ls’s “–time-style” parameter. BSD’s ls does not have this value. MacPorts’ coreutils port contains gls (GNU’s ls) that does support the parameter. So here is my script to move movies into a sub folder based on the movies creation date.

for filename in *.MP4; do
    datepath="$(gls -l --time-style=+%Y-%m-%d $filename | awk '{print $6}')"
    echo "$datepath"
    if ! test -e "$datepath"; then
        mkdir -pv "$datepath"
    fi
    mv -v $filename $datepath
done

Check if a file exists on a remote server

I was working on a copy WordPress site to a local machine script, and I wanted to check if the remote path was a WordPress site.
Here is the code I used.

CHECKCMD="ls /path/to/wp-config.php | grep wp-config.php > /dev/null; echo \$?"
CHECKFILE=$(ssh $SRCSERVER $CHECKCMD)
if [ $CHECKFILE -eq 0 ]; then
	echo "file exists"
fi