Extension Attribute showing free space on a secondary volume

chris_kemp
Contributor III

Just a little story about tonight's task. :-)

Due to a slight modification in our Final Cut Pro setups, I'm concerned with being able to quickly see the available space on our standard data volume. I checked the Extension Attributes page here at the Nation and found Boot Volume Free Space, a very simple script (I like simple!) that goes like this:

#!/bin/bash

free=`diskutil info / | grep "Free Space"| awk '{print $4}'`

echo "<result>"${free%.*}"</result>"

Pretty close...but it needs a couple of minor modifications to suit my needs. First, we need to change / to the appropriate volume, of course:

unit=`diskutil info /Volumes/Data Drive/ | grep "Free Space"| awk '{print $4}'`

Once I set this & ran recon on a group of machines, I found another problem: the output of this command puts out the number returned in the Free Space field - but it does not print the unit of measure! I saw several entries like 496, 197, etc - now, I know these are in GB, but several of my group are reading "1"...it was a moment before I realized that it wasn't because the drives were almost full, but that this meant 1 TB. Soo...let's try:

#!/bin/bash

free=`diskutil info /Volumes/Data Drive/ | grep "Free Space"| awk '{print $4}'`

unit=`diskutil info /Volumes/Data Drive/ | grep "Free Space"| awk '{print $5}'`

echo "<result>"${free%.*} $unit"</result>"

Perfect! Now, I get back meaningful readings (496 GB, 1 TB, etc).

And thus concludes a day (er, night) in the life. Onward...

6 REPLIES 6

iJake
Valued Contributor

Why not just use df?

df -h /Volumes/Data Drive/ | awk '{print $4}'

Saves you some steps and has built in human readable generation.

mm2270
Legendary Contributor III

@Chris, the only issue I would see with the way you've got it is that it would need to be set up as String output. You can't really take advantage of setting the EA as an Integer since it would have stuff like GB, TB, etc in the output. I don't really know how important that is to you or anyone else, but if it is, for example, if you wanted to do a more than / less than comparison with Smart Groups, that could complicate things.

If that's the case, I would do something like this, which will always give you output in GB, but in the case of a machine with less than 1 GB of available space, it would correctly report it as something like 0.8, as an example. Conversely, for a Mac with more than 1 TB of free space, it would report as 1000 or higher (1000 GBs)

#!/bin/sh

Raw=$( df -m / | awk '{getline; print $4}' )

Avail=$( echo "scale=1; x=$Raw / 1024; if(x<1) print 0; x" | bc )

echo "<result>$Avail</result"

Its using bc (bash calculator) which can handle floating point numbers, and give output like 125.5, e.g and then formats the output with awk in case it turns out to be less than "1"
If you wanted to see additional decimals, such as 125.52, change the scale to "2" or higher.
If you want "whole" numbers instead, just remove the scale=1; part.
Oh, and the above is of course only looking at the boot volume. Change the "Raw" variable to look at whatever other volume you wanted of course.

Hope that helps anyone that runs across this and wants integer values returned.

acdesigntech
Contributor II
#!/bin/sh

BootKB=`df -k / | grep disk0 | awk '{print $4}'`
let BootGB=$BootKB/1024/1024

echo "<result>$BootGB</result>"

Less overhead if you pipe everything right to awk though like Mike suggests. I still feel that 'bc' uses too many resources, especially if you have dozens of EAs running.

My code ends up giving you an estimate - the OS says I have 46GB free, and my script says 43. So depends on what you're looking for.

mm2270
Legendary Contributor III

Andrew, using the above doesn't work for me because our volumes for 10.8.x Macs are using FileVault 2, which means the boot volume is disk1, not disk0. You could "genericize" that by grepping for just "disk", but in addition why not just use awk's regex matching and get rid of one pipe?

df -k / | awk '/disk/{print $4}'

I like the idea of simplifying it with a simpler math operation though. I hadn't heard that 'bc' was resource intensive, but I suppose that's possible.

acdesigntech
Contributor II

yeah i really need to get my butt in gear with regexes. I didn't know awk could do that, but then I don't know much about awk. Also wasn't aware of the whole disk1 thing with filevault 2, but yeah that could cause some issues.

I've been on my migration script quest to get the sizes of data folders that will be migrated when someone gets a new Mac, so we can then automate testing to see if all the data got moved within X%, rather than paying a tech to visually compare sizes like we do right now.

I have to use 'bc' for the calculations since bash can't natively do floating point math, and I read somewhere, I think it might have been [stackoverflow.com](stackoverflow.com) that 'bc' uses more system resources since it's a call to an external program. I haven't noticed much when running my migration scripts, but I would think in this type scenario where plenty of other things are going on in the foreground, we'd want to squeeze as much performance out of the EAs as possible.

mm2270
Legendary Contributor III

Andrew, change your division number in your script from 1024 to 1000. I think you'll find that your results more closely match what you see in the Finder for free disk space.
I couldn't figure out myself why there was such a difference, but then I recalled that Apple changed the OS back several versions to use 1000 as the division for megabytes and gigabytes instead of 1024. My memory is fuzzy on exactly when (10.5 or 10.6 perhaps?) but I do recall there was a big hubbub about it when it happened. People who upgraded to the new OS that weren't aware of the change suddenly thought that they were getting more free disk space. Lol!

Though I don't really know if using 1000 or 1024 is more accurate if one intended to closely match what the Finder reported then I'd use 1000.