[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Quilt-dev] Another shell re-write of backup-files.
From: |
Kaz Kylheku |
Subject: |
[Quilt-dev] Another shell re-write of backup-files. |
Date: |
Thu, 17 Mar 2011 18:26:27 -0700 |
User-agent: |
Roundcube Webmail/0.4 |
Hey everyone,
Recently I became interested in a quilt that consists only of shell
scripts.
I did find Martin Quinson's script from 2007 in the list archives,
as well as Jan Delvare's followup.
Noting the performance problems inherent in launching numerous
utilities for each file that is processed, and also noting
remarks about the -z option being deprecated, I took a few
liberties and followed a different approach, leading to the following:
#!/bin/bash
#
# Shell script replacement for quilt's backup-files utility
# Proof-of-concept alpha code
# Mar 17, 2011
# Kaz Kylheku <address@hidden>
#
#
# Main concepts:
#
# - Goal is to avoid invoking a process for each file name
# - We use the CPIO utility for creating hard-linked backups; CPIO
pass-through
# mode can take list of names and create hard links (in pass-through
mode).
# - Use tree-to-tree recursive cp to restore a backup (taking
everything
# in the backup, ignoring the file list).
# - To touch files on restore, if requested, we can do a find + xargs
+ touch
# over the backup instead, prior to restoring it.
# - Added files (i.e. backups of nonexistent files) are represented as
a
# specially named file containing an explicit list, and not as
zero-length
# files. This eases the implementation, and lets us back up/restore
# zero-length files!
#
set -eu # bail on any errors, and unbound variable uses
opt_prefix=
opt_suffix=
opt_file=
opt_backup=
opt_restore=
opt_remove_backup=
opt_keep_backups=
opt_silent=
opt_touch=
opt_nolink=
usage()
{
cat <<!
Usage: $0 [-B prefix] [-f {file|-}] [-sktL] [-b|-r|-x] {file|-} ...
Create hard linked backup copies of a list of files
read from a file (or standard input), or from the
argument list.
-b Create backup
-r Restore the backup
-x Remove backup files and empty parent directories
-k When doing a restore, keep the backup files
-B Path name prefix for backup files
-z Unsupported, obsolete option
-s Silent operation; only print error messages
-f Read the filenames to process from file (- = standard input)
-t Touch original files after restore (update their mtimes)
-L Ensure that when finished, the source file has a link count of 1
!
}
if ! options=`getopt -o B:f:brxkstLh -- "$@"` ; then
usage
exit 1
fi
eval set -- "$options"
while true
do
case "$1" in
-B)
opt_prefix="$2"
shift 2 ;;
-f)
opt_file="$2"
shift 2 ;;
-b)
opt_backup=B
shift ;;
-r)
opt_restore=R
shift ;;
-x)
opt_remove_backup=D
shift ;;
-k)
opt_keep_backups=y
shift ;;
-s)
opt_silent=y
shift ;;
-t)
opt_touch=y
shift ;;
-L)
opt_nolink=y
shift ;;
-h)
usage
exit 0 ;;
--)
shift
break ;;
esac
done
if [ $# -eq 0 -a -z "$opt_file" ] ; then
echo "Error: specify input file names as arguments or via -f option"
echo
usage
exit 1
fi
if [ $# -ge 1 -a -n "$opt_file" ] ; then
echo "Error: conflict: both -f and file name argument given"
echo
usage
exit 1
fi
if [ $# -gt 1 -a "$1" == "-" ] ; then
echo "Error: if - is specified, then no other arguments can be added"
echo
usage
exit 1
fi
if [ -z "$opt_prefix" ] ; then
echo "Error: specify backup/restore directory with -B"
echo
usage
exit 1
fi
temp_list=$(mktemp "${TMP_DIR:-/tmp}/backup-files-tl-XXXXXX")
file_list=$(mktemp "${TMP_DIR:-/tmp}/backup-files-fl-XXXXXX")
noex_list=$(mktemp "${TMP_DIR:-/tmp}/backup-files-ne-XXXXXX")
cleanup()
{
rm -f $temp_list $file_list $noex_list
}
trap cleanup exit
#
# capture the file list into the $temp_list file
#
if [ -n "$opt_file" -a "$opt_file" == "-" -o "$1" == "-" ] ; then
cat > $temp_list
elif [ -n "$opt_file" ] ; then
cat "$opt_file" > $temp_list
else
# IFS trick. The string literal here contains a newline
( IFS="
"
echo "$*" > $temp_list )
fi
#
# separate name list into existing and nonexisting
#
$file_list
$noex_list
while read name ; do
if [ -e "$name" ] ; then
echo "$name" >> $file_list
else
echo "$name" >> $noex_list
fi
done < $temp_list
if [ $opt_silent ] ; then
echo "$0: operating on these files:"
cat $file_list
fi
case $opt_backup$opt_restore$opt_remove_backup in
B )
if [ $opt_nolink ] ; then
cpio --quiet -pd "$opt_prefix" < $file_list
else
cpio --quiet -pdl "$opt_prefix" < $file_list
fi
mv $noex_list "$opt_prefix/.#new-files#"
;;
R )
if [ $opt_nolink ] ; then
cp -a "$opt_prefix"/. .
else
if [ $opt_touch ] ; then
find "$opt_prefix" -type f | xargs touch
fi
cp -rlf "$opt_prefix"/. .
fi
if [ -z "$opt_keep_backups" ] ; then
rm -rf "$opt_prefix"
fi
# Trick! .#new-files# list gets copied along with the files from
# the backup directory to the working directory: we process
# it and remove it.
xargs rm -f < .#new-files#
rm -f .#new-files#
;;
D )
rm -rf "$opt_prefix"
;;
* )
# either no operation was specified, or multiple operations
# were been specified, like -b and -r.
usage
exit 1
;;
esac
- [Quilt-dev] Another shell re-write of backup-files.,
Kaz Kylheku <=
- Re: [Quilt-dev] Another shell re-write of backup-files., Kaz Kylheku, 2011/03/18
- Re: [Quilt-dev] Another shell re-write of backup-files., Jean Delvare, 2011/03/18
- Re: [Quilt-dev] Another shell re-write of backup-files., Kaz Kylheku, 2011/03/18
- Re: [Quilt-dev] Another shell re-write of backup-files., Kaz Kylheku, 2011/03/18
- Re: [Quilt-dev] Another shell re-write of backup-files., Jean Delvare, 2011/03/18
- Re: [Quilt-dev] Another shell re-write of backup-files., Kaz Kylheku, 2011/03/18
- Re: [Quilt-dev] Another shell re-write of backup-files., Jean Delvare, 2011/03/18