Creating a Phantom Disk Image?

Discussion in 'OS X Mountain Lion (10.8)' started by VideoBeagle, Dec 9, 2013.

  1. VideoBeagle macrumors 6502a

    Joined:
    Aug 17, 2010
    Location:
    App Q&A testing by request.
    #1
    I don't know if what I want to do is even possible...

    I would like to create a disk image of a hard drive that has the full file structure in it, folders, files....but no actual data...so like a 100 mb zip file called this.zip on the original would show up on the image as this.zip but just be a few kb.

    I'd like to send a navigable image of a hard drive thru email. I could make a file list but that would be really unwieldy if there's a better option.
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    Yes, it's possible.

    I thought about ways to do this, and I see two basic approaches:
    1. Copy the entire original disk or folder to the destination, then go through and truncate every file to zero length.
    2. Traverse the directory tree of the original disk or folder, and replicate every directory on the destination, then for each original file, create a zero-length file.

    One problem with approach #1 is that it requires copying huge amounts of data, just to truncate it (toss it). Another problem is that things like color tags, creator codes, "Open with" assignments, etc. aren't as easy to remove or truncate as the data in the copied file. These can add up to a significant amount.

    One problem with approach #2 is it won't preserve alias files, symlinks, hard-links, etc. without some extra fiddling around. For a reusable program, such fiddling might be a worthwhile investment for the developer. For a one-off program, not so much.


    So here's the steps and the code.

    I've given it as an Automator workflow containing two script actions: one AppleScript (for user interaction), then one shell script (for doing the work).

    1. Launch Automator.app, and create a new Workflow from the template-chooser that comes up.
    2. Drag a Run AppleScript action to the workflow sequence, then replace the entire prototype script with this:
      Code:
      try
      	choose folder with prompt "Choose the folder to make Phantom from."
      	return POSIX path of result
      on error
      	return "-"
      end try
      
    3. Drag a Run Shell Script action to the end of the workflow, and replace its entire prototype script with this:
      Code:
      echo "got: $1"
      
      [ "$1" == "-" ] && echo "Stopped" && exit
      
      [ ! -d "$1" ] && echo "Must be a directory: $1" && exit
      
      OUT="$HOME/Desktop/Phantom"
      
      mkdir -p "$OUT"
      exit 0  ## early_stop
      
      cd "$1"
      find . -type d -exec mkdir -p "$OUT/"{} \;
      find . -type f -exec touch "$OUT/"{} \;
      
    4. At the upper right of the Run Shell Script action's pane, locate the "Pass input:" popup and set it to "as arguments". It defaults to "to stdin".
    5. Save the workflow.
    6. Run it.
    7. It should ask you to choose a folder to make the phantom from. Do so. It should then make an empty folder named "Phantom" on your desktop. Confirm it does this. If it doesn't do this, post again, providing any error message from the Results view of the workflow.
    8. If the "Phantom" folder is created correctly, then find this line in the shell script:
      Code:
      exit 0  ## early_stop
      and change it to this:
      Code:
      #exit 0  ## early_stop
      That is, insert a # character at the start of that line. This converts the line into a shell comment, which means it's not executed, which means that the commands coming after it WILL be executed.
    9. Save the workflow, then Run it again. Choose a folder. I suggest choosing a smallish folder with sub-folders and files, or at least not a huge folder with hundreds or thousands of files. We're still only doing testing at this point.
    10. When the workflow completes, the "Phantom" folder on your Desktop should now contain a replica of the original's folder structure, and every file should be zero bytes in length. If it doesn't do this, post again, providing any error message from the Results view of the workflow.
    11. At this point, you can trash the test-case "Phantom" folders on your Desktop, then run the workflow and choose the real disk or folder you want to phantomize.

    If something in the above steps fails or doesn't work, post again.

    If you want an explanation of anything in the scripts, ask again, with a specific question about a specific part of the script. I used some unconventional idioms for concise checking of the input parameter. The rest is pretty conventional shell scripting.

    This workflow can also be enhanced. For example, it could allow you to name the output folder, place it somewhere other than Desktop, report any errors it finds during the scan, create a disk-image to write the phantom to directly, etc. All of those things take extra development work, which also means extra time for testing.
     
  3. VideoBeagle, Dec 11, 2013
    Last edited: Dec 11, 2013

    VideoBeagle thread starter macrumors 6502a

    Joined:
    Aug 17, 2010
    Location:
    App Q&A testing by request.
    #3
    Wow! That looks great! I'll give this a try.

    I found that the DiskCatalogMaker that came with Toast will make what I want as well...but it only works for people who would have that program (and a a Mac). And I've been unsusccsful so far with a search for if there's a windows program that can import it's files.

    i'll give your code a try and let you know!

    *************
    EDIT:
    *1st test: Phantom folder created!
    *2nd test, small folder with subfolders, works! (84mb ->90items)
    *3rd test, small folder with Phantom folder already there. Files get added to existing folder. New files in a sub folder get added to the appropriate subfolder, so changes to the real folder could be synched to the subfolder.
    *4th test, large folder with subfolders (6.48gb, 687 items) works...though 72 more items seem to show up...maybe resource forks or .DS_Store 's?

    didn't notice that on previous test with small folder, so will retest that.

    *5th test, small folder for file # inaccuracy...90 items to 90 items.
    *6th test, medium sized folder-more items. (915MB - 1926 items) - 5 more items in phantom folder

    Compare two folders using Chronosync's analyzer...no file discrepancy found...on a test sync, no files not on original are found on phantom (intentional file discrepancy added to confirm test works).

    Prelim conclusion: File discrepancy is based on how Finder's Get Info relays # of items and invisible files.
    ****************************

    This is incredible! Exactly what I was looking for PLUS it helps me with some automator/applescript/scripting education I've been trying to learn. I may tool around with it, see about adding some interface functionality for my own knowledge, but this is perfect!

    Thanks so much!
     

    Attached Files:

  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    Yes, they do. I considered it a feature (a free but useful side-effect).

    If you want a clean slate to start with, then trash any existing Phantom folder on your Desktop first. Or just rename it.


    The extra items almost certainly aren't due to resource forks. A resource-fork is a named xattr of an existing file. It won't be a separate file, EXCEPT on non-HFS file-systems. Then it's a "companion file" whose name starts with "._", and those WILL be replicated by the code I gave.

    I did not exclude files that start with "." or "._", because that seemed like a little too much liberty in deciding what to replicate. That exclusion (i.e. of ".*" or "._*" files) can be added, if it's important to you. It's not a big or difficult addition.

    If Finder isn't counting ".DS_Store" files, then it should be consistent. That is, any ".DS_Store" files in the zero-length replica would be counted or not, the same as what's in the original.


    That could be. I don't know how Finder determines its item count. Experiments could be done, but since your check shows no actual discrepancy, it doesn't seem worthwhile at this point.

    You're welcome. I'm glad it worked out.
     
  5. VideoBeagle thread starter macrumors 6502a

    Joined:
    Aug 17, 2010
    Location:
    App Q&A testing by request.
    #5
    A couple of things I've found...if you copy a drive (as opposed to a folder) the script will error on a few of the .files that need admin access to copy. They seem to be the final things copied, so not a big problem.

    A drive with 583.35 GB (577,669 items) takes about 51 minutes to clone on my i7 iMac, and the 0kb Phantom folder takes about 3.6 minutes to zip (I used automator to do it rather than the compress service as the finder crashed once with that).
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    Try this change.

    In the shell script part, replace these two lines:
    Code:
    find . -type d -exec mkdir -p "$OUT/"{} \;
    find . -type f -exec touch "$OUT/"{} \;
    
    with these two lines:
    Code:
    find . \( -name '.?*' -prune \) -or \( -type d -exec mkdir -p "$OUT/"{} \; \)
    find . \( -name '.?*' -prune \) -or \( -type f -exec touch "$OUT/"{} \; \)
    
    Then save the workflow and test it.

    This should have the effect of:
    1. Skipping all files whose name starts with dot.
    2. Skipping every directory whose name starts with dot, including that directory's entire contents.

    A simple way to make a test-case that contains dot-directories is to create a disk-image, mount it, then copy some files to it. This will trigger Spotlight indexing and other stuff that creates dot-dirs on the volume.
     
  7. VideoBeagle thread starter macrumors 6502a

    Joined:
    Aug 17, 2010
    Location:
    App Q&A testing by request.

Share This Page