Specific fields from macOS Command “diskutil apfs list”

would appreciate inputs on the subject. I have the output from the macOS (High Sierra;FileSystem :APFS) command – diskutil apfs list. Sample output is given below:

+-- Container disk5 1B5FE22B-6F4F-4EB9-8AA3-D326E4E940DF
|   ====================================================
|   APFS Container Reference:     disk5
|   Size (Capacity Ceiling):      250140434432 B (250.1 GB)
|   Minimum Size:                 192333017088 B (192.3 GB)
|   Capacity In Use By Volumes:   186220453888 B (186.2 GB) (74.4% used)
|   Capacity Not Allocated:       63919980544 B (63.9 GB) (25.6% free)
|   |
|   +-< Physical Store disk4s2 E6FF882B-995C-4C60-B164-76923667F8A1
|   |   -----------------------------------------------------------
|   |   APFS Physical Store Disk:   disk4s2
|   |   Size:                       250140434432 B (250.1 GB)
|   |
|   +-> Volume disk5s1 7BB363F8-A658-4B6C-A4B4-778AC782785E
|   |   ---------------------------------------------------
|   |   APFS Volume Disk (Role):   disk5s1 (No specific role)
|   |   Name:                      Macintosh HD (Case-insensitive)
|   |   Mount Point:               Not Mounted
|   |   Capacity Consumed:         181760897024 B (181.8 GB)
|   |   FileVault:                 Yes (Locked)
|   |
|   +-> Volume disk5s2 48A79DA5-1228-4F5A-8851-5178B91D2310
|   |   ---------------------------------------------------
|   |   APFS Volume Disk (Role):   disk5s2 (Preboot)
|   |   Name:                      Preboot (Case-insensitive)
|   |   Mount Point:               Not Mounted
|   |   Capacity Consumed:         66613248 B (66.6 MB)
|   |   FileVault:                 No
|   |
|   +-> Volume disk5s3 D46C3FA0-5B9D-4E13-9327-EEFB483F692E
|   |   ---------------------------------------------------
|   |   APFS Volume Disk (Role):   disk5s3 (Recovery)
|   |   Name:                      Recovery (Case-insensitive)
|   |   Mount Point:               Not Mounted
|   |   Capacity Consumed:         1033371648 B (1.0 GB)
|   |   FileVault:                 No
|   |
|   +-> Volume disk5s4 3E852266-E0C3-48AB-ACAD-D73CEE0134F1
|       ---------------------------------------------------
|       APFS Volume Disk (Role):   disk5s4 (VM)
|       Name:                      VM (Case-insensitive)
|       Mount Point:               Not Mounted
|       Capacity Consumed:         3221250048 B (3.2 GB)
|       FileVault:                 No

My objective was:

  1. Output disk container along with GUID for fileVault status of “Yes (Locked)” .
  2. Store the GUID for fileVault status of “Yes (Locked)” into a variable.

I came up with the following:

diskutil apfs list|awk '/[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}$|.l/{print}'

Output:

+-- Container disk5 1B5FE22B-6F4F-4EB9-8AA3-D326E4E940DF
|   Size (Capacity Ceiling):      250140434432 B (250.1 GB)
|   Capacity In Use By Volumes:   186220453888 B (186.2 GB) (74.4% used)
|   Capacity Not Allocated:       63919980544 B (63.9 GB) (25.6% free)
|   +-< Physical Store disk4s2 E6FF882B-995C-4C60-B164-76923667F8A1
|   |   APFS Physical Store Disk:   disk4s2
|   +-> Volume disk5s1 7BB363F8-A658-4B6C-A4B4-778AC782785E
|   |   APFS Volume Disk (Role):   disk5s1 (No specific role)
|   |   FileVault:                 Yes (Locked)
|   +-> Volume disk5s2 48A79DA5-1228-4F5A-8851-5178B91D2310
|   |   APFS Volume Disk (Role):   disk5s2 (Preboot)
|   |   FileVault:                 No
|   +-> Volume disk5s3 D46C3FA0-5B9D-4E13-9327-EEFB483F692E
|   |   APFS Volume Disk (Role):   disk5s3 (Recovery)
|   |   FileVault:                 No
|   +-> Volume disk5s4 3E852266-E0C3-48AB-ACAD-D73CEE0134F1
|       APFS Volume Disk (Role):   disk5s4 (VM)
|       FileVault:                 No

Any inputs to correct/modify the code are welcome :). Thanks in advance

Answer

Going with Mark Plotnick’s suggestion of converting the structured XML output of

diskutil apfs list -plist

into JSON and parsing it with jq. The jq utility is available from Homebrew on macOS.

This has to be done in two steps as the plutil needs to read a regular file:

diskutil apfs list -plist >list.xml
plutil -convert json -o list.json list.xml

From the generated JSON file, we may extract the APFS volume UUID of all volumes that have FileVault enabled and that are locked, using

jq -r '.Containers[].Volumes[] | select(.FileVault == true and .Locked == true) | .APFSVolumeUUID' list.json

Assigning this to a variable, in one “single” command:

locked_uuids=$(
    diskutil apfs list -plist >list.xml
    plutil -convert json -o list.json list.xml
    jq -r '.Containers[].Volumes[] | select(.FileVault == true and .Locked == true) | .APFSVolumeUUID' list.json
    rm -f list.xml list.json
)

Note that the above command overwrites and removes the two files list.xml and list.json in the current directory. You may want to create temporary files using mktemp instead:

locked_uuids=$(
    tmpxml=$(mktemp)
    tmpjson=$(mktemp)
    diskutil apfs list -plist >"$tmpxml"
    plutil -convert json -o "$tmpjson" "$tmpxml"
    jq -r '.Containers[].Volumes[] | select(.FileVault == true and .Locked == true) | .APFSVolumeUUID' "$tmpjson"
    rm -f "$tmpxml" "$tmpjson"
)

And, for convenience, you may want to put those commands into a shell function and call that instead (using bash here):

list_locked_vaults () {
    local tmpxml=$(mktemp)
    local tmpjson=$(mktemp)
    diskutil apfs list -plist >"$tmpxml"
    plutil -convert json -o "$tmpjson" "$tmpxml"
    jq -r '.Containers[].Volumes[] | select(.FileVault == true and .Locked == true) | .APFSVolumeUUID' "$tmpjson"
    rm -f "$tmpxml" "$tmpjson"
}

locked_uuids=$( list_locked_vaults )

Leave a Reply

Your email address will not be published. Required fields are marked *