[TD="class: number"]1[/TD]
[TD="class: content"]#!/bin/bash[/TD]
[TD="class: number"]2[/TD]
[TD="class: content"]#[/TD]
[TD="class: number"]3[/TD]
[TD="class: content"]# Creates a copy with timestamp of the file(s) given in argument.[/TD]
[TD="class: number"]4[/TD]
[TD="class: content"]# Optionally removes old copies[/TD]
[TD="class: number"]5[/TD]
[TD="class: content"]#[/TD]
[TD="class: number"]7[/TD]
[TD="class: content"]#[/TD]
[TD="class: number"]8[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]9[/TD]
[TD="class: content"]KEEPNUM=0 # 0 = disabled[/TD]
[TD="class: number"]10[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]11[/TD]
[TD="class: content"]function printhelp() {[/TD]
[TD="class: number"]12[/TD]
[TD="class: content"] echo "usage: $0 [-k <num>] [-yv] file_to_backup [file_to_backup...]" >&2[/TD]
[TD="class: number"]13[/TD]
[TD="class: content"] echo "options:" >&2[/TD]
[TD="class: number"]14[/TD]
[TD="class: content"] echo " -k keep last <num> backups and remove older files" >&2[/TD]
[TD="class: number"]15[/TD]
[TD="class: content"] echo " -y assume 'yes' if backup a directory" >&2[/TD]
[TD="class: number"]16[/TD]
[TD="class: content"] echo " -v verbose" >&2[/TD]
[TD="class: number"]17[/TD]
[TD="class: content"] exit 1[/TD]
[TD="class: number"]18[/TD]
[TD="class: content"]}[/TD]
[TD="class: number"]19[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]20[/TD]
[TD="class: content"][ "$1" == "" ] && printhelp[/TD]
[TD="class: number"]21[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]22[/TD]
[TD="class: content"]while getopts ":k:yvh" opt[/TD]
[TD="class: number"]23[/TD]
[TD="class: content"]do[/TD]
[TD="class: number"]24[/TD]
[TD="class: content"] case $opt in[/TD]
[TD="class: number"]25[/TD]
[TD="class: content"] k)[/TD]
[TD="class: number"]26[/TD]
[TD="class: content"] [ ${OPTARG:0:1} = "=" ] && KEEPNUM=${OPTARG/=} || KEEPNUM=$OPTARG[/TD]
[TD="class: number"]27[/TD]
[TD="class: content"] ;;[/TD]
[TD="class: number"]28[/TD]
[TD="class: content"] y)[/TD]
[TD="class: number"]29[/TD]
[TD="class: content"] YES="y"[/TD]
[TD="class: number"]30[/TD]
[TD="class: content"] ;;[/TD]
[TD="class: number"]31[/TD]
[TD="class: content"] v)[/TD]
[TD="class: number"]32[/TD]
[TD="class: content"] VERBOSE="v"[/TD]
[TD="class: number"]33[/TD]
[TD="class: content"] ;;[/TD]
[TD="class: number"]34[/TD]
[TD="class: content"] *)[/TD]
[TD="class: number"]35[/TD]
[TD="class: content"] printhelp[/TD]
[TD="class: number"]36[/TD]
[TD="class: content"] ;;[/TD]
[TD="class: number"]37[/TD]
[TD="class: content"] esac[/TD]
[TD="class: number"]38[/TD]
[TD="class: content"]done[/TD]
[TD="class: number"]39[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]40[/TD]
[TD="class: content"]shift $(($OPTIND-1))[/TD]
[TD="class: number"]41[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]42[/TD]
[TD="class: content"]FILENAMES=$*[/TD]
[TD="class: number"]43[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]44[/TD]
[TD="class: content"][[ $KEEPNUM == [0-9]* ]] || printhelp[/TD]
[TD="class: number"]45[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]46[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]47[/TD]
[TD="class: content"]# pre check[/TD]
[TD="class: number"]48[/TD]
[TD="class: content"]ERROR=0[/TD]
[TD="class: number"]49[/TD]
[TD="class: content"]for FILENAME in $FILENAMES; do[/TD]
[TD="class: number"]50[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]51[/TD]
[TD="class: content"] if [ ! -e $FILENAME ]; then[/TD]
[TD="class: number"]52[/TD]
[TD="class: content"] echo "file not found or unsupported filetype: $FILENAME" >&2[/TD]
[TD="class: number"]53[/TD]
[TD="class: content"] ERROR=1[/TD]
[TD="class: number"]54[/TD]
[TD="class: content"] fi[/TD]
[TD="class: number"]55[/TD]
[TD="class: content"] if [ -L $FILENAME ]; then[/TD]
[TD="class: number"]56[/TD]
[TD="class: content"] echo "file is a symlink: $FILENAME" >&2[/TD]
[TD="class: number"]57[/TD]
[TD="class: content"] ERROR=1[/TD]
[TD="class: number"]58[/TD]
[TD="class: content"] fi[/TD]
[TD="class: number"]59[/TD]
[TD="class: content"] if [ -d $FILENAME -a $ERROR != 1 ] ; then[/TD]
[TD="class: number"]60[/TD]
[TD="class: content"] if [ "$YES" != "y" ]; then[/TD]
[TD="class: number"]61[/TD]
[TD="class: content"] echo -n "Do you want to backup the whole directory $FILENAME? [Y/n] "[/TD]
[TD="class: number"]62[/TD]
[TD="class: content"] read YN[/TD]
[TD="class: number"]63[/TD]
[TD="class: content"] if [ "$YN" == 'n' ] ; then[/TD]
[TD="class: number"]64[/TD]
[TD="class: content"] echo OK, nothing backuped >&2[/TD]
[TD="class: number"]65[/TD]
[TD="class: content"] exit 1[/TD]
[TD="class: number"]66[/TD]
[TD="class: content"] else[/TD]
[TD="class: number"]67[/TD]
[TD="class: content"] YES=y[/TD]
[TD="class: number"]68[/TD]
[TD="class: content"] fi[/TD]
[TD="class: number"]69[/TD]
[TD="class: content"] fi[/TD]
[TD="class: number"]70[/TD]
[TD="class: content"] fi[/TD]
[TD="class: number"]71[/TD]
[TD="class: content"]done[/TD]
[TD="class: number"]72[/TD]
[TD="class: content"]if [ "$ERROR" == 1 ] ; then[/TD]
[TD="class: number"]73[/TD]
[TD="class: content"] echo 'Operation stopped because of previous errors. Nothing backuped!' >&2[/TD]
[TD="class: number"]74[/TD]
[TD="class: content"] exit 1[/TD]
[TD="class: number"]75[/TD]
[TD="class: content"]fi[/TD]
[TD="class: number"]76[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]77[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]78[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]79[/TD]
[TD="class: content"]# copy files[/TD]
[TD="class: number"]80[/TD]
[TD="class: content"]for FILENAME in $FILENAMES; do[/TD]
[TD="class: number"]81[/TD]
[TD="class: content"] # evtl / am Ende entfernen[/TD]
[TD="class: number"]82[/TD]
[TD="class: content"] FILENAME=$(echo $FILENAME | sed 's#/$##')[/TD]
[TD="class: number"]83[/TD]
[TD="class: content"] cp -pr$VERBOSE $FILENAME $FILENAME.`date +%Y%m%d-%H%M%S`[/TD]
[TD="class: number"]84[/TD]
[TD="class: content"] RETVAL=$?[/TD]
[TD="class: number"]85[/TD]
[TD="class: content"] if [ "$RETVAL" -ne 0 ] ; then[/TD]
[TD="class: number"]86[/TD]
[TD="class: content"] echo Copy error at file: $FILENAME >&2[/TD]
[TD="class: number"]87[/TD]
[TD="class: content"] exit $RETVAL[/TD]
[TD="class: number"]88[/TD]
[TD="class: content"] fi[/TD]
[TD="class: number"]89[/TD]
[TD="class: content"]done[/TD]
[TD="class: number"]90[/TD]
[TD="class: content"] [/TD]
[TD="class: number"]91[/TD]
[TD="class: content"]# remove old files[/TD]
[TD="class: number"]92[/TD]
[TD="class: content"]if [ $KEEPNUM -gt 0 ]; then[/TD]
[TD="class: number"]93[/TD]
[TD="class: content"] for FILENAME in $FILENAMES; do[/TD]
[TD="class: number"]94[/TD]
[TD="class: content"] # evtl / am Ende entfernen[/TD]
[TD="class: number"]95[/TD]
[TD="class: content"] FILENAME=$(echo $FILENAME | sed 's#/$##')[/TD]
[TD="class: number"]96[/TD]
[TD="class: content"] I=0[/TD]
[TD="class: number"]97[/TD]
[TD="class: content"] for FILE in `ls -dr $FILENAME.????????-??????`; do[/TD]
[TD="class: number"]98[/TD]
[TD="class: content"] I=$(( $I + 1 ))[/TD]
[TD="class: number"]99[/TD]
[TD="class: content"] [ $I -gt $KEEPNUM ] && rm -rf$VERBOSE $FILE[/TD]
[TD="class: number"]100[/TD]
[TD="class: content"] done[/TD]
[TD="class: number"]101[/TD]
[TD="class: content"] done[/TD]
[TD="class: number"]102[/TD]
[TD="class: content"]fi[/TD]