[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Quilt-dev] Another shell re-write of backup-files.
From: |
Kaz Kylheku |
Subject: |
Re: [Quilt-dev] Another shell re-write of backup-files. |
Date: |
Fri, 18 Mar 2011 09:50:18 -0700 |
User-agent: |
Roundcube Webmail/0.4 |
On Fri, 18 Mar 2011 10:18:27 +0100, Jean Delvare <address@hidden>
wrote:
> Hi Kaz,
>
> On Friday 18 March 2011 02:26:27 am Kaz Kylheku wrote:
>> Hey everyone,
>>
>> Recently I became interested in a quilt that consists only of shell
>> scripts.
>
> You're not the only one. I'm happy to see momentum grow in this
> direction.
>
I did some further hacking on this last night, sliding the program
under quilt and getting it to work, including adding new files,
and pushes and pops with file creating/deleting patches.
This version does not change the backup format, so everything works.
I will fix the touch logic so that it doesn't diddle the backup files.
It's clear that we can't do a faithful restore with timestamps intact
if it's done the way I have it.
#!/bin/bash
#
# Shell script replacement for quilt's backup-files utility
# Tested to some extent under quilt.
# Mar 18, 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. [WRONG]
# - 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=
all_backup_files=
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.
The argument list "-" means "every regular file in
the backup directory specified by the -B prefix.
-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. Should have trailing slash.
Without a trailing slash, the behavior is different from the
C implementation.
-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 file that holds raw list of names
temp_list=$(mktemp "${TMP_DIR:-/tmp}/backup-files-tl-XXXXXX")
# temp file that holds names of files that exist
file_list=$(mktemp "${TMP_DIR:-/tmp}/backup-files-fl-XXXXXX")
# temp file that holds names of nonexistent files
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" == "-" ] ; then
cat > $temp_list
elif [ -n "$opt_file" ] ; then
cat "$opt_file" > $temp_list
elif [ "$1" == "-" ] ; then
all_backup_files=y
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
case $opt_backup$opt_restore$opt_remove_backup in
B )
if [ $all_backup_files ] ; then
echo "Error: \"-\" argument makes no sense for backup action"
echo
usage
exit 1
fi
if [ $opt_nolink ] ; then
cpio --quiet -pd "$opt_prefix" < $file_list
else
cpio --quiet -pdl "$opt_prefix" < $file_list
fi
umask 0111 # so touched files are 0666
# escaping issues here: we are assuming opt_prefix
# doesn't contain # or things interpreted by sed
sed -e "s#.*#$opt_prefix&#" < $noex_list | xargs touch
;;
R )
if [ -z $all_backup_files ] ; then
echo "Error: restoring individual files is not supported"
exit 1
fi
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
find "$opt_prefix" -type f -size 0c \
| cut -c "$((1+${#opt_prefix}))-" \
| xargs rm -f
if [ -z "$opt_keep_backups" ] ; then
rm -rf "$opt_prefix"
fi
;;
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, 2011/03/17
- 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 <=
- 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
- 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/19
- Re: [Quilt-dev] Another shell re-write of backup-files., Jean Delvare, 2011/03/19
- Re: [Quilt-dev] Another shell re-write of backup-files., Kaz Kylheku, 2011/03/19