Page 1 of 1

Get contents of disk images

PostPosted: Sun Feb 06, 2011 5:39 pm
by invictus26
I really like how Hazel has the ability to extract archive files and then delete the archive, but I also wanted the same thing for disk images. I couldn't get it to work with built-in methods, so I wrote this script:

Code: Select all
# Destination for disk image contents, change if desired
destPath = "/Volumes/Macintosh HD/Downloads/"

# Get path of disk image from Hazel
path = ARGV[0]

# Mounts the disk image, agrees to the license agreement and supresses the Finder window that normally pops up. I tried using -noautoopen, but that didn't work for me, so I used -nobrowse, which hides the mounted image from the Finder entirely. Change if desired
output = %x[echo "y" | hdiutil attach -nobrowse #{path.dump}]

# Gets the path of the new mounted volume
volPath = output.split("\n")[-1].split("\t")[-1]

# Gets every item in the disk image
items = %x[cd #{volPath.dump}; ls].split("\n")

# Goes through all the items and copies anything that's not an alias (Usually to the Applications folder) to the destination path specified above
items.each do |item|
  if !%x[GetFileInfo -a #{volPath.dump + "/" + item}].include?("A")
    %x[cp -R #{volPath.dump + "/" + item + " " + destPath.dump}]
  end
end

# Unmounts the disk image and moves it to the trash
%x[hdiutil unmount #{volPath.dump}; mv #{path.dump} ~/.Trash]


You can modify the destination path "destPath" at the top to set where you want the contents of the disk image to go. Just paste the code into a text editor and give it the extension ".rb". Then just have Hazel look for disk images and run an embedded shell script:

Code: Select all
ruby "/Path/To/Script/CoolScript.rb" "$1"


I can also modify it to move any applications straight to the Applications folder if that would be useful. I tested this out on a few application disk images, so let me know if anything isn't working right and I'll try to fix it.

Re: Get contents of disk images

PostPosted: Wed Feb 09, 2011 1:26 pm
by Mr_Noodle
I actually thought about having the Unarchive action handle DMGs as well. The problem is if the DMG has a license agreement. While as a user, you can suppress that/automatically agree in your script, I can't circumvent that for you for legal reasons. Unfortunately, Apple changed the way hdiutil works. It used to bring up the GUI but now brings up a terminal interface for the license agreement. For me to do it properly, I would need to replicate that GUI myself, including deciphering the eula format in the DMG.

Thanks for the script.

Re: Get contents of disk images

PostPosted: Tue Feb 15, 2011 4:25 pm
by invictus26
Here is an updated version of the script. Now it will create a folder in the destination directory to hold the disk image contents if there are multiple files. It also handles contents with spaces in their names better.

Code: Select all
# Destination for disk image contents, change if desired, but make sure to keep the trailing slash.
destPath = "/Volumes/Macintosh HD/Downloads/"

# Get path of disk image from Hazel
path = ARGV[0]

# Mounts the disk image, agrees to the license agreement and supresses the Finder window that normally pops up. I tried using -noautoopen, but that didn't work for me, so I used -nobrowse, which hides the mounted image from the Finder entirely. Change if desired
output = %x[echo "y" | hdiutil attach -nobrowse #{path.dump}]

# Gets the path of the new mounted volume
volPath = output.split("\n")[-1].split("\t")[-1]

# Gets every item in the disk image
items = %x[cd #{volPath.dump}; ls].split("\n")

# Looks to see if there is more than one non-alias file in the disk image
i = 0
items.each do |item|
  i += 1 if !%x[GetFileInfo -a #{(volPath + "/" + item).dump}].include?("A")
end

# Make a folder to hold disk image contents if there are multiple files
if i > 1
  destPath = destPath + volPath.split("/")[-1] + "/"
  %x[mkdir -p #{destPath.dump}]
end

# Goes through all the items and copies anything that's not an alias (Usually to the Applications folder) to the destination path specified above.
items.each do |item|
  if !%x[GetFileInfo -a #{(volPath + "/" + item).dump}].include?("A")
      %x[cp -R #{(volPath + "/" + item).dump + " " + destPath.dump}]
  end
end

# Unmounts the disk image and moves it to the trash
%x[hdiutil unmount #{volPath.dump}; mv #{path.dump} ~/.Trash]

Re: Get contents of disk images

PostPosted: Sun Feb 09, 2014 4:08 pm
by musecaptain
This script sounds great! However I haven't been able to make it work. I get an error:
Code: Select all
Hazel_DMG_to_folder.rb:8: syntax error, unexpected tIDENTIFIER, expecting end-of-input
output = %x[echo "y" | hdiutil attach -nobrowse #{path.dump}]
                   ^

== End script output ==


Any ideas on how to fix this?

Re: Get contents of disk images

PostPosted: Mon Apr 02, 2018 3:35 pm
by Martenzi
I had issues with unmounted the disks so Disk Utility kept a list of all dmg-s and I was "forced" to unmount manually. They seemed to put workload on my system and I have a bit of OCD on leaving used DMG-s mounted.

I changed the last part and removed the "move to trash" as I keep my DMGs in folder for temp storage until I trust my current High Sierra build.

By using
Code: Select all
hdiutil eject
instead of
Code: Select all
detach -force
I got the script running smoothly and no issues with Finder.

# Unmounts the disk image
Code: Select all
%x[hdiutil eject #{volPath.dump}]