Eject Command in AppleScript

Discussion in 'Mac Programming' started by Gene Shalit, Jan 22, 2010.

  1. Gene Shalit macrumors newbie

    Joined:
    Nov 29, 2009
    #1
    I've recently set my computer to hibernate instead of sleep, but I've found that when the computer hibernates, external drives are not ejected properly. I found an AppleScript command that ejects everything, but that includes the disc in the CD/DVD drive (which I don't want to be ejected). Here's the script I have at this point:
    Code:
    tell application "Finder" to eject (every disk whose ejectable is true)
    tell application "System Events"
    	sleep
    end tell
    Basically what I want it to say is:
    Code:
    tell application "Finder" to eject (every disk whose isCDdrive is false)
    tell application "System Events"
    	sleep
    end tell
    ...where "isCDdrive" is something that the computer would actually understand. So what I'm asking is does anyone know what the generic descriptor of the computer's CD/DVD drive is?

    UPDATE:
    I changed the script to say:
    Code:
    tell application "Finder" to eject (every disk whose owner privileges is read write)
    tell application "Finder" to eject (every disk whose owner privileges is write only)
    tell application "System Events"
    	sleep
    end tell
    This does the trick for now. Even when there is a blank CD where I have read and write privileges, it's not ejected with this script. The only problem I can see at this point is if I have an external drive that is read only. If that ever happens, it won't be ejected; however, I don't know if a read only drive can be damaged if removed without being ejected.

    If anyone knows if a read only drive can be damaged if removed without ejecting, or if anyone knows of a better way to script this, feel free to post.

    UPDATE:
    I've found a new problem. If I mount a disk image, and I have write privileges, it will be ejected when I run the script (which I don't want to happen), so an alternative to the script I have now would be preferred.
     
  2. mysterytramp macrumors 65816

    mysterytramp

    Joined:
    Jul 17, 2008
    Location:
    Maryland
    #2
    I've tried both of these scripts on my system. I have one external drive with multiple partitions. I added a dmg as well as a CD. I can't find anything in AppleScript that tells you for sure that you can generalize that a drive is a CD/DVDs unless you're willing to assume that all read-only disks are CD/DVDs

    Would it be wrong to do something like this:

    Code:
    tell application "Finder"
    	set diskList to the disks
    	repeat with dl in diskList
    		set theName to the name of dl
    		display dialog theName
    		if theName is "The name of a disk I want to eject" then
    			eject dl
    		else if theName is "The name of the second disk I want to eject" then
    			eject dl
    		else if theName is "The name of the third disk I want to eject" then
    			eject dl
    		end if
    	end repeat
    end tell
    
    You might also try this:

    Code:
    set nameList to {}
    
    tell application "Finder"
    	set diskList to the disks
    	repeat with dl in diskList
    		set nameList to nameList & the name of dl
    	end repeat
    	set ejectList to choose from list nameList with prompt "Which disks do you want to eject" with multiple selections allowed
    	repeat with eL in ejectList
    		try
    			set ejectDisk to (disks whose name is eL)
    		on error
    			set ejectDisk to (disks whose name is eL) -- this is absolutely ridiculous
    		end try
    	end repeat
    end tell
    On the second script ... I found a combo of two disks that burped a weird AS error, but ONLY that combo. Trapping the error and repeating the line somehow corrected it. FYI, the second script doesn't include any error checking. It assumes you won't try to eject your startup disk.

    mt
     
  3. Gene Shalit thread starter macrumors newbie

    Joined:
    Nov 29, 2009
    #3
    When I tried working with the first script you gave, I got this:
    The second one's no good for what I want to do because I just want a simple one-click application that ejects all damageable disks and then hibernates the computer.


    I also forgot to mention in the first post that I have very little experience with writing AppleScripts.
     
  4. mysterytramp macrumors 65816

    mysterytramp

    Joined:
    Jul 17, 2008
    Location:
    Maryland
    #4
    Yikes! Repaired now.

    What do you mean by damageable?

    If the names of the disks remain static, that is you're working with the same computer each time this is run, the first script might be your best bet. Alternatively, you could check the privileges of each disk and decide based on the combinations of privileges whether you want to eject or not.

    Getting back to your first post:

    Is there such a thing as a disk that is a write-only disk? I'd guess this was a typo but AS doesn't burp on this, so it must be OK.

    mt
     
  5. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #5
    The script refers to owner privileges. This corresponds to the Posix owner permission bits. So write-only is valid.

    Note that a volume may be mounted read-only even though owner privileges are something else. For example, insert a CD or DVD (any media other than DVD-RAM) and execute the 'mount' command in Terminal. Then execute ls -la on the mount-point of the CD or DVD. Compare with the Applescript:

    Code:
    tell app "Finder" to get properties of (last disk)
    There's probably a way to parse the output of 'mount', or the output of 'diskutil info mountPoint', to tell you whether something is mounted read-only, or which physical drive it's on. See the man pages for mount and diskutil, and try some things.
     
  6. wsha macrumors newbie

    Joined:
    Aug 21, 2011
    #6
    I also had the problem of wanting to eject all ejectable disks from my laptop via AppleScript except for the optical disc drive. For some reason the read/write and "free space is 0" solutions that come up on Google weren't working for me. Here is what I eventually came up with. I don't guarantee that it will work for other people but you can give it a try:

    Code:
    tell application "Finder"
    	-- This script should eject every ejectable disk except for optical drives
    	-- Determining which drives are optical drives is a little tricky and some 
    	-- assumptions are made in searching for them.  Read the comments below.
    	
    	
    	-- Without the escape characters the shell command below is
    	-- "diskutil list | awk '/^\dev/ {print $1}' | sed 's/\//\/\//g'
    	-- The awk command returns a return separated list of the names of the current disks
    	-- The sed command (which is a mess of escape characters) replaces each "/" in
    	-- the nams of the disks with "\/". This is necessary so that the /'s will be 
    	-- properly escaped when they are used again in a do shell script command.
    	set diskListStr to do shell script "diskutil list | awk '/^\\/dev/ {print $1}' | sed 's/\\//\\\\\\//g'"
    	-- Turn the string of disk names into an AppleScript list
    	set AppleScript's text item delimiters to return
    	set diskList to every text item of diskListStr
    	
    	-- Search through the disks in diskList for any disk that has the "Optical"
    	-- in its diskutil info results.
    	set opticalDrives to ""
    	-- The repeat loop below performs the following shell commands on each diskName
    	-- in diskList:
    	--
    	-- First it does:
    	-- "diskutil info diskName | sed 's/^[ \t]*//g' | grep Optical
    	-- which searches diskutil info for any lines beginning with "Optical".  Usually only optical
    	-- drives match this criteria.
    	--
    	-- Then it does:
    	-- "diskutil list diskName | awk 'NF > 5' | awk '{{for(i=3;i<=NF-3;i++){printf "%s",$i}}printf "\n"} | sed 's[ \t]*$//'"
    	-- which searches through diskutil list for any lines with more than five fields.  
    	-- diskutil list outputs a table of information with five columns about each partition of the disk.
    	-- One of these columns is the name of the partition.  Not all partitions have names, but the ones
    	-- that show up in Finder as ejectable disks use the name shown here.  The SIZE column uses 
    	-- the format "### KB/MB/GB" so it alwasy has two words.  That is why we look for lines with more than
    	-- five fields.  Then we pull out the entries between the first two and the last three.  These are the 
    	-- entries that are not part of the partition name.  We put all of the names thus found into a list.
    	-- Below we will eject all disks not in the list.
    	-- Note: I am not positive that some disks do not have extra named partitions on CDs/DVDs beyond 
    	-- the ones that show up as disks in Finder.  If they do and there is a naming conflict with
    	-- another disk, that name will be added to the noEject list and the corresponding disk will not be ejected.
    	repeat with currentDisk in diskList
    		set currentScript to "diskutil info " & currentDisk & " | sed 's/^[ \\t]*//' | grep Optical"
    		set currentString to ""
    		try
    			set currentString to do shell script currentScript
    		end try
    		if length of currentString > 0 then
    			set currentScript to "diskutil list " & currentDisk & " | awk 'NF > 5' | "
    			set currentScript to currentScript & "awk '{{for(i=3;i<=NF-3;i++){printf \"%s \",$i}}printf \"\\n\"}'"
    			set currentScript to currentScript & " | sed 's/[ \\t]*$//'"
    			try
    				set opticalDrives to do shell script currentScript
    			end try
    		end if
    	end repeat
    	set AppleScript's text item delimiters to return
    	set noEjectList to every text item of opticalDrives
    	-- Add the startup disk to the list for good measure, though it should not
    	-- be ejectable any way.
    	copy name of startup disk to the end of noEjectList
    	
    	-- Loop through the list of ejectable disks and eject any that are not in the 
    	-- noEjectList created above
    	set currentDisks to the name of every disk whose ejectable is true
    	repeat with tempDisk in currentDisks
    		if (tempDisk is not in noEjectList) then
    			eject tempDisk
    		end if
    	end repeat
    	
    end tell
     
  7. tresean1 macrumors member

    Joined:
    Mar 12, 2012
    #7
    How did you do that, if you don't mind sharing?
     
  8. balamw Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #8
    From the other thread you've posted in:

    Open terminal and type
    Code:
    man pmset
    to make sure this is still valid for your Mac.

    B
     

Share This Page