Level: Intermediate, Version: FM 8 or later

A Simple Backup Script, revisited

In October 2011 I posted a simple backup script that has made my development life easier, but of course that version was for .fp7 files only (the release of FM 12 being six months in the future), and when I began converting files to FileMaker 12, I realized that the backup script was not intelligently rolling with the changes. So recently I modified the script to accommodate both .fp7 and .fmp12 files, and also to be more flexible with regards to separators within the backup file name, e.g.,

Rather than repeatedly referring the reader back to the earlier article, I have “deprecated” the prior one and reproduced it here with appropriate changes, and have also updated the demo file (see below).

Broadly speaking, FileMaker developers fall into three categories: a) those who do all their development on local files; b) those who do all their development on hosted files; and c) those who sometimes develop locally, and sometimes in a hosted environment. I happen to fall into category “c”, and suspect that many of my colleagues do as well.

A few years back I put together a basic script to create on-the-fly backups when working on local files. Any time I make regular use of a tool or technique, I figure there must be at least a few other people out there who will find it useful as well. And a big thank you to Bruce Robertson, who gives so much to the FileMaker community, for writing the Mac-specific code for this demo: Backup-Revisited

Disclaimer: This is not a substitute for a well-thought-out offsite backup scheme… just a quick and dirty way to make backups during development without having to first close the file, take the time to compress it, decide what to name it or where to store it. As with all techniques on this site, view with skepticism, and use at your own risk.

Overview: the backup script generates a compressed copy of the file with an OS-friendly timestamp prepended to the file name, e.g.,

2012.06.25 - 15.42.24 ~ backup,revisited.fmp12

…and saves it in this location, creating the folder structure as necessary, like so:

(current folder)/Backup/Saturday/

I’d like to take a brief walk through the script and make a few observations on the way.

First we declare a number of variables. When I’m working through something, I find it much easier to declare a number of separate variables, and use them as building blocks, rather than write one ultra-efficient code statement. I find this helps me debug more quickly, and also, when I come back later, it makes it easier for me to figure out what’s going on.

The term “filespec” signifies not just the file name, but the location as well. In this case the file will be stored two folders “below” whatever folder our solution happens to be in. The $timestamp variable is sliced and zero-padded in this particular manner a) to remove characters that are forbidden on either the Macintosh or Windows platforms, and b) so that if a number of separate backups are later sorted by name, they will sort in chronological order. (I know, I know, they can be sorted that way at the OS level by sorting on the creation or modification date/time — just humor me, okay?)

Next, do we need to bail out?

If we’ve made it this far, then it’s safe to proceed. Now it’s time to ensure that the folder structure is in place, which we can accomplish via the Send Event script step on Windows…

…or via Perform AppleScript on the Macintosh.

And the remainder of the script is self-explanatory.

This script is completely portable. You can copy it from the demo file, paste it into your solution and immediately start using it. If you convert your solution from an earlier version of FileMaker to FileMaker 12, the backup script will continue to purr along like a contented kitten.

Think of this version as a starting point. No doubt it can be improved and extended in various ways, for example…

  1. During active development, have an on-timer script trigger run the backup script every x minutes
  2. As part of the backup routine, call a shell script (or perform Applescript, or use a plug-in) to make a zipped copy, and then…
  3. FTP the zipped copy to an off-site location

As always, comments or suggestions for improvement are welcome.

A big thank you goes to Bruce Robertson, who gives so much to the FileMake community, and who wrote the Mac-specific code for this demo.

18 thoughts on “A Simple Backup Script, revisited”

  1. Thanks for this, Kevin. Very useful. I just want to offer two variations on your file-spec-building theme:

    1. If you make all the variables you set to be global you can review them after the script runs if an error occurs. Clear the variables if no error occurs. (Or conversely, throw them into global variables if an error _does_ occur.)

    2. You can also set up your variables to be internally scoped in a Let statement in just one Set Variable step and then use something like Developer Assistant to review each value as the script runs. (You open up the original script while the active script is paused in the debugger and view each variable value in context.) This gives you the requisite granular troubleshooting capability while still only taking up one script step.

  2. Thanks, Kevin. I have a script that saves a copy of my file to my Dropbox account and then another script that uses Install OnTimer Script that runs the first script every 10 or 20 minutes depending on the complexity of what I am working on. This second script is activated when the file is opened. If I open a new window, I have another script that turns off the timer so I don’t end up getting multiple copies saved.

    If, for any reason, FileMaker crashes, I simply throw the damaged file away, pull the copy off of Dropbox and redo what I just did. (If I had done something very complicated, I might open the old one long enough to use that to refresh my memory).

    Since every file that I’m working on has this script running, it doesn’t matter much if FM crashes or not as I always know that I have a backup.

  3. Thanks for this Kevin.

    I’ve built something very similar over time but didn’t get round to the xplat folder creation/management.

    Only addition I’ve have is if modifier key then I save as empty clone. Also did version with dialogs asking if clone, compressed or both and 2nd dialog saying where eg. desktop or backup folder (still portable).

    With FM12 maybe I need another option to save as ‘self-contained’ although can’t see the need just yet.

  4. This is a really great post. Script work here will be very helpful. I’m curious why you don’t run a local FM server, develop on your hosted databases and use server backup scheduling to create interval backups? You could even schedule the offsite backup, shell script to compress/move your copies around. It also protects against some crashes. Just curious

    Great work, thanks for the post!

    1. Hello Chiyoko, thanks for your comment. As I said in the article, many developers sometimes work on hosted files and sometimes on local files. I did not mean to imply that local development is a “best practice”. This is a script for when one is *not* working on FMS.

  5. That’s makes sense, great info! Since I started running my own server, I rarely work without it, just for peace of mind. Thanks again.

  6. We sell vertical market solutions (mostly peer-to-peer or single user) and I’m using this script to allow users to make a backup when they quit the solution.

    However, I discovered that this script requires full access privileges to work – it’s fine if you’re doing it as the developer, because you’re already logged in appropriately, but if you implement this for users, it will not work in some circumstances (subject to their privileges). Therefore, always set the script to run with full access privileges (the tick at the bottom of the script dialog box).

  7. Hi Kevin,

    Great blog, great posting, frequent visitor.

    Just playing with this very useful backup script and I discovered one minor issue. If you happen to have an apostraphe in any of your folder paths down to where your database lives, the script will barf out three error messages. Running on a Mac 10.7.4 FM12.

    My solution was to take the apostraphe out of my path names. It is probably not that uncommon an occurrence to name a folder “So-And-So’s Development Folder”.


    1. Thank you for this fantastic information, I’m very appreciative. Doug has stated an error that I have come across as well. My Macintosh internal hard drive is named “Joe’s MacBook Pro”. This script returns:

      sh: -c: line 0: unexpected EOF while looking for matching `”
      sh: -c: line 1: syntax error: unexpected end of file

      As expected, if I remove the apostrophe in my hard drive’s name, the script works flawlessly.

      Is there any way around this without having to rename my hard drive?

      Does this have to do with the apostrophes in the Set Variable $script:

      “mkdir -p ‘volumes/” & $newpath & “‘” ?

      I’ve tried a multitude of ways to change the way that path is written to no avail.

      Any guidance would be most appreciative!

  8. Wonderful contribution.
    After switching to FM12 my previous backup didn’t work
    doubtless a simple glitch
    Fortunately I decided to look on line and found your wonderfully general
    and elegant solution.

    Thanks a bunch

  9. I have been using this backup script and recently changed my Container Storage to “External Secure Storage”. I changed the “Save as portion to “Self-Contained” in your script. I now receive a Dialog Sign In Box that displays my Account Name and asks for a Password. I assume this is normal since I configured Container Storage to External Secure? Is this expected behavior?

    1. Hi Mike, I don’t know the answer to your question. Perhaps someone who does will chime in.
      — Kevin

      1. Thanks Kevin, I did a Save As Self Contained Copy without using the Backup Script and received the same Dialog Box so I guess it has to do with the External Secure Storage.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.