Cygwin BASH function to open the latest version of a document

One handy function I’ve added to .bashrc (so it is always available) under Cygwin (the LINUX command environment for Windows) works out the current working version of a document. It assumes that you keep copies that have a version number or date in the file name that will sort correctly.

# Opens the latest version of a file using the Windows default application
# Assumes that you have a range of files that can be identified using some for of prefix
#   and that the last part of the file contains a version number or date that sorts in the correct order
#   e.g. myfile-lots-of-rubbish-20090720-01.doc & myfile-lots-of-rubbish-20090723.01.doc
# Two arguments are required. The first is the PATH to search in. The 2nd is the shared file prefix (e.g. 'myfile-lots-of-rubbish-')
#   Put single quotes around the arguments to prevent them from being GLOBed by the shell.
# Only searches in the GIVEN path, not subfolders.
# Use with an ALIAS to have an easy way of opening a specific file from the shell
function cyOpenLatest {
    # We have to use find rather than ls because of shell expansion issues in the arguments (and problems with spaces in file/folder names)
    res=`find "$1" -iname "${2}*" -type f -prune -printf '%f\n' | sort -r | head -1`
    # Work out the file type from the .ext
    ext=`echo $res | sed "s/.*\.//"`
    # Add whatever you want to this list above the *)
    case $ext in
        doc*) TYPE="in Word" ;;
        xls*) TYPE="in Excel" ;;
        ppt*) TYPE="in PowerPoint" ;;
        vsd*) TYPE="in Visio" ;;
        *) TYPE="with Windows default application"
    esac
    if [ "$res" != "" ]; then
        echo "Opening [$res] $TYPE"
        cygstart "$res"
    fi
}

You can use it with an alias like this:

alias gic="cyOpenLatest '$HOME/Documents/Here is a folder with a space or two/' 'a-document-'"

If you name your documents sensibly such as “a-document-2009-07-20.doc” or “a-document-v01.01.doc”, then the latest version of the file will be opened in the default application

Technorati :
Diigo Tag Search :

Shell script to Back up critical files (using RSYNC)

Following up from my article on backing up USB drives, this recipe backs up the critical files on my desktop to remote storage (a NAS device on my network). Note that PC2 is the desktop to be backed up, SLUG1 (192.168.1.2) is the NAS device and USER1 is the user id doing the backup.

#!/bin/bash

# Backup Key PC2 files to Slug1

# Sync 2007 picture folders
##rsync -rl /home/user1/pictures/2007/  [email protected]:/public/pictures/2007/

# Ensure that /mnt/slug1-root/ is mounted
#if [ ! -e /mnt/slug1-root/user1/backups/PC2/bin/ ]; then
#    mount-slug-root.sh
#fi
# Ensure that /media/slug1-public/ is mounted
#if [ ! -e /media/slug1-public/DISK1.txt ]; then
#    mount-slug-public.sh
#fi

# NOTE that to configure the rsync sessions on SLUG1, edit the file /opt/etc/rsyncd.conf
TOPUB='[email protected]::public'
# Use this form if not using sessions
#TOPUB='[email protected]:/public'
# Or use this form if the remote folder is mounted locally
#TOPUB='/media/slug1-public'
TOJK='[email protected]::pc2'
#TOJK='[email protected]:/user1/backups/PC2'
#TOJK='/mnt/slug1-root/user1/backups/PC2'

JKDT=`date --rfc-3339=date`
JKLOG="/home/user1/Backups/pc2backup_$JKDT.log"

echo "Starting PC2 backup at `date`" >$JKLOG
echo "=================================================================="
echo "Starting PC2 backup at `date`"
echo "The log file is at $JKLOG, all backups are to SLUG1/pc2 or SLUG1/public"
echo " "

#--out-format=FORMAT     output updates using the specified FORMAT
#--log-file=FILE         log what we're doing to the specified FILE
#--chmod=CHMOD
#--exclude=PATTERN       exclude files matching PATTERN
#     --exclude-from=FILE     read exclude patterns from FILE
#     --include=PATTERN       don't exclude files matching PATTERN
#     --include-from=FILE
#--dry-run
#OPTS='--verbose --archive --recursive --links --perms --executability --owner --group --devices --specials --times --human-readable --delete --delete-after --stats --ipv4 --progress --password-file=/home/user1/bin/tmppw.tmp --dry-run'
OPTS='--verbose --archive --recursive --links --executability --devices --specials --times --human-readable --delete --delete-after --stats --ipv4 --progress'
echo "Back up various bits - WARNING: DELETES files from destination" >>$JKLOG

RSYNC_PASSWORD=`kdialog --password "Password for [email protected] please:"`
#kdialog --password "Password for [email protected] please:" >~/tmppw.tmp

echo "Backups to SLUG1/pc2"
echo " "
# ** JK BACKUPS **
echo "user1/bin"
echo "rsync $OPTS /home/user1/bin/ $TOJK/bin/" >>$JKLOG
rsync $OPTS /home/user1/bin/ $TOJK/bin/ >>$JKLOG 2>&1
echo "=========================================" >>$JKLOG
echo "user1/backups"
echo "rsync $OPTS /home/user1/Backups/ $TOJK/Backups/" >>$JKLOG
rsync $OPTS /home/user1/Backups/ $TOJK/Backups/ >>$JKLOG 2>&1
echo "=========================================" >>$JKLOG
#echo "rsync $OPTS /home/user1/Downloads/ $TOJK/Downloads/" >>$JKLOG
#rsync $OPTS /home/user1/Downloads/ $TOJK/Downloads/ >>$JKLOG 2>&1
#echo "=========================================" >>$JKLOG

echo "Backups to SLUG1/public"
echo " "
# ** Backups to public **

echo "user1/ebooks"
echo "rsync $OPTS /home/user1/eBooks/ $TOPUB/ebooks/sorting/" >>$JKLOG
rsync $OPTS /home/user1/eBooks/ $TOPUB/ebooks/sorting/ >>$JKLOG 2>&1
echo "=========================================" >>$JKLOG

echo "user1/pictures/Lnnnn"
echo "Back up picture files - WARNING: Does NOT delete files from destination" >>$JKLOG
OPTS='--verbose --archive --recursive --links --times --human-readable --stats --ipv4'
echo "rsync $OPTS /home/user1/Pictures/L2007/ $TOPUB/pictures/2007/" >>$JKLOG
rsync $OPTS /home/user1/Pictures/L2007/ $TOPUB/pictures/2007/ >>$JKLOG 2>&1
echo "rsync $OPTS /home/user1/Pictures/L2008/ $TOPUB/pictures/2008/" >>$JKLOG
rsync $OPTS /home/user1/Pictures/L2008/ $TOPUB/pictures/2008/ >>$JKLOG 2>&1
echo "=========================================" >>$JKLOG

echo "user1/backups/usbpen1 & usbpen2"
echo "rsync $OPTS /home/user1/Backups/USBPEN1/ $TOJK/Backups/USBPEN1/" >>$JKLOG
rsync $OPTS /home/user1/Backups/USBPEN1/ $TOJK/Backups/USBPEN1/ >>$JKLOG 2>&1
echo "=========================================" >>$JKLOG
echo "rsync $OPTS /home/user1/Backups/USBPEN2/ $TOJK/Backups/USBPEN2/" >>$JKLOG
rsync $OPTS /home/user1/Backups/USBPEN2/ $TOJK/Backups/USBPEN2/ >>$JKLOG 2>&1
echo "=========================================" >>$JKLOG

echo "Google Earth places"
echo "Back up Google Earth myplaces.kml" >>$JKLOG
rsync $OPTS /home/user1/.googleearth/myplaces.kml $TOPUB/maps+walks/pc2-myplaces.kml >>$JKLOG 2>&1
echo "=========================================" >>$JKLOG

#echo '' >~/tmppw.tmp
#rm ~/tmppw.tmp

echo " "
echo "ENDING PC2 backup at `date`" >>$JKLOG
echo "ENDING PC2 backup at `date`"
echo "=================================================================="

# To run under schedule
#    Log
#    Replace password

I have a similar script that runs on the NAS device which backs key files on that to a remote hosting service on a different continent! That way, I don’t have to worry about the house burning down or being burgled.

Automatically Backing up a USB Drive with RSYNC (KDE)

USB Drives of all kinds need to be backed up and the best backup is an automatic one (it’s the only way to make sure that it gets done!).

So here is one recipe for doing just that using RSYNC and some BASH scripting magic.

I’ve split this into two files. You don’t have to do this of course and one may well be better for you. I used two because I can run the second one manually as well. Put everything in autorun.sh if you want to backup each drive individually, however, note that KDE produces an annoying extra dialog (a security warning) asking if you really want to run the autorun.

  • autorun.sh
    This resides in the root of the USB drive and is executed automatically by KDE when the drive is detected (though not if the drive is attached when booting)
  • usb-backup-manual.sh
    This is a bit of a nasty hack, I have manually configured a list of drives that might be attached so that I can back them all up together. Not elegant but it works for me.

autorun.sh

#!/bin/bash

# KDE will automatically run an executable file called: .autorun, autorun or autorun.sh (in that order)
# Alternatively, a non-executable file called .autoopen or autoopen can contain a file name
# of a non-executable file on the media which will be opened with the default app for that file.
# See: http://standards.freedesktop.org/autostart-spec/autostart-spec-0.5.html#mounting

# Also see: http://b50.roxor.pl/~michal/linux/autorun.txt
# for some interesting ideas

# Where are we running from? e.g. /media/usbpen1
mediaDir=$(echo $0|sed 's/autorun//')

kdialog --title "USB Drive Backup" --yesno "I'd like to backup the USB drives, can I?"
if [ $? = 0 ]; then
echo " OK Selected, I'm going"
echo "Autobackup run: `date`" >usb-linux-auto-backup.log
exec ~/bin/usb-backup-manual.sh
else
echo " Cancel selected, so do nothing - bye."
fi
</code></pre><h4>usb-backup-manual.sh</h4><pre><code>
#! /bin/bash

#http://www.sanitarium.net/golug/rsync_backups.html
#http://www.mikerubel.org/computers/rsync_snapshots/
#http://rsync.samba.org/examples.html

echo "Starting USB Backup: `date`"
echo "Starting USB Backup: `date`" >~/Backups/usb-backup-manual.log

# From
MNT="/media"
# To
TO="/home/julian/Backups"

dcopRef=`kdialog --progressbar "Starting backup - press cancel to stop further processing (no next step)" 4`
dcop $dcopRef showCancelButton true

#until test "true" == `dcop $dcopRef wasCancelled`; do
for f in "CF2G1" "SD1G1" "USBPEN1" "USBPEN2"
do
dcop $dcopRef setLabel "Backing up $MNT/$f  ==>  $TO"
echo "--------------------------------------"
echo "$f  ==>  $TO"
inc=$((`dcop $dcopRef progress` + 1))
sleep 2
if [ -e $MNT/$f ]; then
  dcop $dcopRef setProgress $inc
  RSCMD="rsync --recursive --times --delete-during --stats --human-readable -h $MNT/$f $TO"
  echo $RSCMD
  echo $RSCMD  >>~/Backups/usb-backup-manual.log
  $RSCMD
  dcop $dcopRef setLabel "RSYNC for $f finished"
else
  dcop $dcopRef setProgress $inc
  dcop $dcopRef setLabel "$MNT/$f not mounted"
  echo "$MNT/$f not mounted"
  echo "$MNT/$f not mounted"  >>~/Backups/usb-backup-manual.log
fi
echo "======================================="
sleep 2
done

dcop $dcopRef close

echo "End: `date`"
echo "End: `date`" >>~/Backups/usb-backup-manual.log

Note the use of KDialog to provide a minimal GUI. In the second file, KDialog produces a progress bar.

Also note the RSYNC parameters. These are always painful to get to grips with so it is nice to have an example to work from. In this case I am backing up so I am making sure that the backup is an exact copy of the original (as opposed to synchronising which would allow changes to happen on either side).