#!/bin/bash # #***************************************************************************** # syncit - synchronize files * #***************************************************************************** # Author: Christian Habermann * # christian (at) habermann-net (point) de * # * # Version: 1.0.0 * # * # Date: 27. Jan. 2004 * # * # Copyright 2003 Christian Habermann, distributed under the terms of GPL * # * # History: - V0.1.0, 20. Nov. 2003 * # initial version * # * # - V1.0.0, 27. Jan. 2004 * # first release * # - documentation improved * # - added ASK_BEFORE_STARTING_SCRIPT * # ask before starting to synchronize * # - added ASK_BEFORE_SYNCHRONIZING * # ask for each file separately whether it should be * # synchronized or not * # * # * #***************************************************************************** # Description: * # This script can be used to keep shared files on Windows and Linux * # systems up to date. * # * # Typical use case: * # PC at home (e.g. Linux) * # PC at work (e.g. Windows, with cygwin to run this script) * # Data files are carried via USB-memory stick between work and home. * # * # When leaving PC1 to use PC2, start this script on PC1 in order to * # update files on transport device (e.g. USB-memory stick). At PC2 start * # this script in order to update files on PC2. And vice versa. * # * # Date/time of last modification of files on FAT filesystem has a * # resolution of 2 seconds. Seconds can have values of 0, 2, 4, ... 58. * # Linux filesystems have a resolution of 1 second for date/time of last * # modification. * # In order to decide whether files on FAT and Linux-filesystems are * # equally old, it is necessary to reduce date/time resolution to 2 * # seconds for Linux filesystems too. * # This means files with e.g. 34 and 35 seconds are treated as equally old. * # * # * # See below "USER SETTINGS" for how to select files which should be * # synchronized on different systems. * # * # * #***************************************************************************** #***************************************************************************** #***************************** USER SETTINGS ********************************* #***************************************************************************** #*** *** #*** USER: Adapt the following settings to you own needs. *** #*** *** TRANSDEV_LIN="/mnt/penhdd/" # path to transportable device for linux TRANSDEV_WIN="e:/" # and windows MAX_NUM_OF_FILES=20 # max. number of files that can be specified to # be synchronized #*** specify a file *** # For each file, four variables must be specified: # NAME_x: a short text describing type of file # Hint: if you want a well formated output, give all NAME_x # the same length (use spaces if necessary) # FILE_LIN_x: file on Linux system # FILE_WIN_x: file on Windows system # FILE_TRANS_x: file on transport system # # x is a unique number in the range of 1 ... MAX_NUM_OF_FILES # EXAMPLE: keep Opera bookmarks and vim-config-files up to date #NAME_1="Opera Bookmarks" #FILE_LIN_1="$HOME/.opera/opera6.adr" #FILE_WIN_1="c:/programme/Opera7/operadef6.adr" #FILE_TRANS_1="opera/opera6.adr" # #NAME_2="Vim .vimrc " #FILE_LIN_2="$HOME/.vimrc" #FILE_WIN_2="c:/_vimrc" #FILE_TRANS_2="vim/_vimrc" # #NAME_3="Vim .gvimrc " #FILE_LIN_3="$HOME/.gvimrc" #FILE_WIN_3="c:/_gvimrc" #FILE_TRANS_3="vim/_gvimrc" # set this to 0 if you don't want to be asked to start synchronizing ASK_BEFORE_STARTING_SCRIPT=1 # set this to 0 if you don't want to be asked for each file separately whether you # really want to synchronize it or not # ATTENTION: IF THIS IS 0 NEWER FILES ARE COPIED OVER OLDER ONES WITHOUT WARNING. ASK_BEFORE_SYNCHRONIZING=1 # IMPORTANT: set this to 1, else syncit will deny to start. # This is done to ensure that user has configured this script. USER_SETTINGS_DONE=0 #*** end of user's section *** #***************************************************************************** #******************************* CONSTANTS *********************************** #***************************************************************************** ### make some initialisations VERSION="1.0.0" # used to print version number SCRIPTNAME="syncit" # name of file PROGNAME="SyncIt" # name of this tool SYS_LINUX=0 SYS_WINDOWS=1 #***************************************************************************** #******************************* FUNCTIONS *********************************** #***************************************************************************** #***************************************************************************** # input: $1: $name name of what is to be synchronized (e.g. bookmarks,...) * # $2: $file1 file on system * # $3: $file2 file on transport device * #***************************************************************************** # Copy newer file over older file. * # If neither $file1 nor $file2 does exist, don't copy, just print message. * # If just one file exists, copy this to none-existing path/file. * # * # Date/time is in seconds since 1970-1-1 00:00:00 * # To be compatible to vfat-filesystems, granularity of date/time is reduced * # to 2 seconds (date/time can be ..., 1202, 1204, 1206, ... seconds) * # Files with a real date/time of e.g. 1202 and 1203 are considered as files * # which have the same date/time. * # * #***************************************************************************** SYI_Synchronize () { local name=$1 local file1=$2 local file2=$3 echo -n "synchronize $name: " #*** get date/time of file in seconds since 1970-1-1 00:00:00 #*** if file does not exist, date = -1 # get date/time of file 1 with granularity of 2 seconds if [ -e "$file1" ]; then dateF1=$(date -r "$file1" +%s) dateF1=$(($dateF1 - $dateF1 % 2)) else dateF1=-1 fi # get date/time of file 2 with granularity of 2 seconds if [ -e "$file2" ]; then dateF2=$(date -r "$file2" +%s) dateF2=$(($dateF2 - $dateF2 % 2)) else dateF2=-1 fi # if none of the files exist, return if [ $dateF1 -eq -1 ] && [ $dateF2 -eq -1 ]; then echo "no file found" return 1 fi #*** at least one of the files exists, copy newest over oldest #*** if enabled ask before copying #*** if files have identical date/time, do nothing if [ $dateF1 -gt $dateF2 ]; then echo -n "system --> device " awnser="y" # ask before copying? if [ $ASK_BEFORE_SYNCHRONIZING -ne 0 ]; then echo -n "[y, n]?" read -s -n 1 awnser fi if [ "$awnser" == "y" ]; then cp -a "$file1" "$file2" echo "... ok" else echo "... skipped" fi else if [ $dateF1 -lt $dateF2 ]; then echo -n "system <-- device " awnser="y" # ask before copying? if [ $ASK_BEFORE_SYNCHRONIZING -ne 0 ]; then echo -n "[y, n]?" read -s -n 1 awnser fi if [ "$awnser" == "y" ]; then cp -a "$file2" "$file1" echo "... ok" else echo "... skipped" fi else # file 1 and 2 equally old => do nothing echo "... up to date" fi fi } #***************************************************************************** # input: none * # output: SYS_LINUX: linux * # SYS_WINDOWS: windows * #***************************************************************************** # Returns on which system (linux or windows) this script is running. * # If c: exists, windows is assumed, else linux. * # * #***************************************************************************** SYI_WhichSystem() { if [ -d "C:/" ]; then return $SYS_WINDOWS else return $SYS_LINUX fi } #***************************************************************************** #***************************** START OF MAIN ********************************* #***************************************************************************** #*** startup text echo "$PROGNAME V$VERSION " # exit if user has not done settings if [ $USER_SETTINGS_DONE -eq 0 ] ; then echo "ERROR: It seems that $PROGNAME is not configured. Please adapt this" echo " script to your own needs. See header of script for further" echo " information." exit 1 fi # ask user to start synchronizing files if [ $ASK_BEFORE_STARTING_SCRIPT -ne 0 ]; then echo "Do you want to start synchronizing files?" if [ $ASK_BEFORE_SYNCHRONIZING -eq 0 ]; then echo "WARNING: older files are overwritten with newer ones without warning!" fi echo "" echo "press any key to start or ctrl-c to cancel" read -s -n 1 fi #*** get system we are running on (linux or windows?) SYI_WhichSystem system=$? if [ $system -eq $SYS_LINUX ]; then echo "running under Linux" mount "$TRANSDEV_LIN" else echo "running under Windows" fi # main loop: synchronize files for i in $(seq $MAX_NUM_OF_FILES); do #for ((i=1; i <= 10; i++)); do # concatenate string and loop-counter to variable # principle: NAME_${i} expands to string NAME_1 # \$\{NAME_${i}\} builds string ${NAME_1} # finally eval expands this string again eval name=\$\{NAME_${i}\} eval file_trans=\$\{FILE_TRANS_${i}\} eval file_lin=\$\{FILE_LIN_${i}\} eval file_win=\$\{FILE_WIN_${i}\} # if NAMExx is not empty synchronize this file if [ -n "$name" ]; then # synchronize file if [ $system -eq "$SYS_LINUX" ]; then # Linux? SYI_Synchronize "$name" "$file_lin" "$TRANSDEV_LIN$file_trans" else # Windows SYI_Synchronize "$name" "$file_win" "$TRANSDEV_WIN$file_trans" fi fi done #*** clean up if [ $system -eq $SYS_LINUX ]; then sleep 2 # device needs time to get ready for umount umount $TRANSDEV_LIN fi # that's it - bye bye exit 0 # EOF