By Mitch Stuart
Copyright © 2002-2003 FullSpan Software
-
Usage subject to license
Software Version: 1.3
-
Document Version: $Revision: 1.4 $, $Date: 2003/12/31 07:30:21 $
6. Programming and Testing Information
When I am working on the computer, I often feel the need to save interim versions of a file, whether I am writing, programming, doing system administration, working on financial records, etc. A typical case is when I have gotten a program working to a certain degree, and I want to introduce a new feature or try a new algorithm. It's nice to take a snapshot of the file(s) before starting the changes — if the changes don't work out, I can easily revert to the prior version without having to manually remove my changes and reconstruct the file as it was before.
Getting FileSnap
filesnap.pl [options] fileList
FileSnap copies each file and directory named on the command line to the FileSnap destination directory, giving it a new name that is based on the original name, but with a snapshot sequence number embedded. The fileList can be one or more files or directories (or a mixture), and wildcards are allowed.
For example, if you run this command:
filesnap.pl shopping.txt taxes.xls
FileSnap will create two files in the destination directory: shopping_fs0001.txt and taxes_0001.xls. (This example assumes you have set the default destination directory as discussed below.)
You can install FileSnap in a way that makes it more convenient to invoke, by using a short alias for the script name, or (on Windows) using a "Send To" menu entry to snapshot files directly from Windows Explorer:
These installation options are discussed in detail in the Installation section.
FileSnap processes the files you select in the following way:
0001 and increase by one with each execution. The reason for the leading zeroes is to ensure that the filenames sort properly. For example, in an alphabetical directory listing, a_fs2.txtwould sort after a_fs11.txt, which is not what we want. But a_fs0002.txt correctly sorts before a_fs0011.txt.
_fsNNNN", where "fs" is an abbreviation of "FileSnap" and "NNNN" is the 4-digit sequence number.
taxes_0001.xls it will open in Microsoft Excel. If there is no extension, the tag is simply appended to the filename. For example, myfile would become myfile_fs0001.
.bashrc would snapshot as .bashrc_fs0001, not _fs0001.bashrc. The second special case is for compound extensions like .tar.gz. FileSnap has built-in knowledge of two compound extensions: .tar.gz and .tar.Z. FileSnap knows that compound extensions should be treated as a unit. For example, test.tar.gz would snapshot as test_fs0001.tar.gz, not test.tar_fs0001.gz. You can tell FileSnap about other compound extensions using the -extensions option discussed below.
-d) or full names (like -destdir) for the option name. The only required option is the destination directory.
-d[estdir] directory
directory is the directory where the snapshot files will be placed
-m[ove]
-move switch to tell FileSnap to instead move the files you specify to the snapshot directory. This can be useful for archiving files such as daily logs or backups.
-e[xtensions] extensionList
extensionList that you specify are in addition to the .tar.gz and .tar.Z extensions that FileSnap handles by default. Include the period in the extension you specify (for example, -e .foo.bar).
The following options are used mainly for debugging or testing.
-o[utput] outputlevel
outputlevel can be one of the following values: quiet, standard, verbose, or debug. The default is standard.
-n[ocopy]
nocopy option executes the normal FileSnap logic but does not actually copy any files. This is useful in conjunction with the debug outputlevel to ensure that FileSnap will behave as expected (for example, when testing program changes).
FILESNAP_OPT environment variable can be used to specify options rather than having to type them on the command line. For example, you should set FILESNAP_OPT to your default destination directory (for example, "-d c:\backup" or "-d /home/someuser/backup"). Then, each time you run FileSnap, that directory will be used as the snapshot destination.
If you have some compound extensions that you use on a regular basis, you should also include those in your FILESNAP_OPT variable definition.
If you specify an option on the command line, it overrides the setting of that option (if any) in the FILESNAP_OPT variable. This allows you to, for example, set a default destination directory for most executions of FileSnap, but then use an alternate destination on occasion as needed.
src/
a.txt
b.txt
.bashrc
dir1/
c.txt
d.txt
dir1a/
e.txt
dir2/
c.txt
dir3/
f.foo.bar
The following table shows a sequence of FileSnap commands, and the resulting files and directories that are created (this assumes that the destination directory has been specified with the FILESNAP_OPT variable).
| FileSnap Command and Resulting Files | Comments |
filesnap.pl src/a.txt
Creates:
|
The simplest FileSnap case copies a single file. |
filesnap.pl src/*.txt
Creates:
|
This example shows the usage of wildcards. Note that the snapshot sequence number has increased from 0001 to 0002, and the same snapshot tag has been applied to all the files specified in this run of FileSnap. The file a.txt now has two snapshots in the destination directory: a_fs0001.txt and a_fs0002.txt.
|
filesnap.pl src/.bashrc
Creates:
|
This example shows the special-case treatment of a filename beginning with a period. As discussed above, in this case the text following the initial period is treated as the basename of the file, not as the extension. |
filesnap.pl src/dir1 src/dir2
Creates:
|
This example shows how snapshots of directories work. Note that the entire directory, including all of its files and directories, is copied to the destination.
Notice that only the directory name is transformed by the insertion of the snapshot tag. There is no need to transform the filenames of the contained files and directories because they are safely stored underneath the unique snapshot directory name. |
filesnap.pl dir1/c.txt dir2/c.txt
Creates:
|
This examples shows how duplicate filenames are handled. When FileSnap finds a duplicate file or directory name in the list of files to be saved, it increments the snapshot sequence number. This duplicate detection and sequence number change only applies to "top level" files.
The snapshot sequence number is only incremented when it would cause a conflicting filename. This becomes clear by looking at the difference between the previous example and this one. In both cases, two instances of c.txt were copied. But in the previous case, the c.txt files were underneath directories that were copied, whereas in this case the c.txt files are copied as top-level files. |
filesnap.pl -e .foo.bar dir3/*
Creates:
|
This example shows how compound extensions work. Note the placement of the snapshot tag in between the base name and the compound extension. |
filesnap.pl to a local directory, for example, c:\bin\filesnap.pl.
c:\backup\filesnap.
FILESNAP_OPT, with a value that sets the FileSnap destination directory. For example, -d c:\backup\filesnap. (Search in Windows Help for "environment variable" if you need help with this.)
echo %FILESNAP_OPT% and make sure the FILESNAP_OPT variable is set properly.
c:\perl\bin\perl c:\bin\filesnap.pl test.txt
Check the destination directory and make sure the file was saved.
fs.bat (or another name of your choice), and add the following lines (adjust the paths for your environment):
@echo off
c:\perl\bin\perl c:\bin\filesnap.pl %*
Test the batch file with a command like:
fs test.txt
Check the destination directory and make sure the file was saved.
C:\perl\bin\wPerl.exe c:\bin\filesnap.pl
and for the name, enter FileSnap (or another name of your choice).
To test the Send To feature, right-click on a filename in Windows Explorer, select "Send To", and choose FileSnap from the context menu that appears. Check the destination directory to make sure the file was saved.
Note the use of wPerl.exe instead of Perl.exe. wPerl is part of the ActiveState Perl distribution for Windows. (wPerl or a similar program may be available with other distributions also.) It is almost identical to Perl.exe, except that wPerl.exe is marked as a Windows GUI application, whereas Perl.exe is marked as a Windows Console application. If you use Perl.exe from a Send To command, or another GUI launch method, you may see the flash of a Command Prompt (Console) window opening and closing. Because wPerl.exe is marked as a GUI applcation, it does not cause a Command Prompt to open. (If you do not have wPerl.exe available, you should still be able to create a Send To item using the standard Perl.exe.)
filesnap.pl to a local directory, either a user directory such as /home/someuser/bin or a common directory such as /usr/local/bin. Make the script executable with chmod if necessary.
/home/someuser/backup/filesnap.
.bashrc or similar) named FILESNAP_OPT, with a value that sets the FileSnap destination directory. For example:
export FILESNAP_OPT="-d /home/someuser/backup/filesnap"
echo $FILESNAP_OPT and make sure the FILESNAP_OPT variable is set properly.
/home/someuser/bin/filesnap.pl test.txt
Check the destination directory and make sure the file was saved.
.bashrc or similar), for example:
alias fs='/home/someuser/bin/filesnap.pl'
Test the alias with a command like:
fs test.txt
Check the destination directory and make sure the file was saved.
There are ways other than FileSnap to accomplish the same general thing, but those methods have their limitations:
filesnap.pl script, there is also a test script called filesnap_test.pl. Run filensnap_test.pl with no arguments for a usage message. Depending on your Perl version and distribution, to run the filesnap_test.pl (but not filesnap.pl itself) you may need to get the Test::Simple and Test::Harness modules from CPAN if they are not already installed in your environment. Just run filesnap_test.pl with no arguments and you will get a message if the modules are not currently installed in your environment.
FileSnap has been tested primarily on Windows 2000, Windows XP, Cygwin, and Linux. Earlier versions were tested on Solaris and FreeBSD. The testing was done with various versions of Perl, all of which were 5.6.0 or above.
There are two platform-specific issues that had to be addressed in the code. First, Windows does not support shell globbing (expansion of filename wildcard characters by the shell prior to invoking a program). Therefore, if FileSnap encounters the * or ? characters in a filename on the command line, it uses the File::DosGlob 'glob' function to expand the filename into all matching names. Second, Windows paths specified on the command line may include backslashes, which causes problems when doing manipulation of those strings. Fortunately, Perl on Win32 works just fine using forward slashes as the separator character, so FileSnap internally translates backslashes to forward slashes.