Skip to content

Instantly share code, notes, and snippets.

@joevt
Last active May 11, 2023 06:34
Show Gist options
  • Save joevt/6d7a0ede45106345a39bdfa0ac10ffd6 to your computer and use it in GitHub Desktop.
Save joevt/6d7a0ede45106345a39bdfa0ac10ffd6 to your computer and use it in GitHub Desktop.

Revisions

  1. joevt revised this gist May 11, 2023. 1 changed file with 66 additions and 17 deletions.
    83 changes: 66 additions & 17 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # by joevt May 23, 2022
    # by joevt May 10, 2023

    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    @@ -18,6 +18,9 @@ else
    alias directbless=bless
    fi

    # Set this to 1 since some macOS versions will modify disk labels without user action.
    # But you need to run unlockapfsbooter before doing OS updates.
    dolockdisklabels=1

    # dump disk_label file
    dump_label () { local contents; contents=$(xxd -p -c99999 "$1"); echo "${contents:10}" | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }
    @@ -100,7 +103,7 @@ makemultilinedisklabel () {
    local alllines2x=""
    local tempfolder0=""
    local tempfolder=""
    tempfolder0="$(mktemp -d)"
    tempfolder0="$(mktemp -d /tmp/makemultilinedisklabel.XXX)"
    # do the blessing on a temporary disk image so it doesn't do apfs stuff like copy the disk label to preboot of the current system
    tempfolder="$(hdiutil create -volname disklabeltmp -size 600k -fs HFS+ -attach "$tempfolder0/tmp.dmg" | perl -nE 'if (/\/dev\/disk[0-9]+s[0-9]+[^\t]*\tApple_HFS[^\t]*\t(.*)/) { print $1 }')"
    if [[ -z $tempfolder ]]; then
    @@ -151,28 +154,33 @@ makemultilinedisklabel () {
    thelines=$(echo "$thelines" | sed -E "$centercommands s/\./0/g")
    printf "01%04x%04x$thelines" $((${#maxlinewidth} / 2)) "$(echo "$thelines" | wc -l)" | xxd -p -r > "$tempfolder/disk_label$suffix"

    [[ -f "$folder/.disk_label$suffix" ]] && sudo chflags noschg "$folder/.disk_label$suffix"
    # EFI file system converts schg flag to uchg flag, so we set both to no
    [[ -f "$folder/.disk_label$suffix" ]] && {
    sudo chflags noschg,nouchg "$folder/.disk_label$suffix"
    }
    sudo cp "$tempfolder/disk_label$suffix" "$folder/.disk_label$suffix"
    sudo chflags schg "$folder/.disk_label$suffix"
    ((dolockdisklabels)) && sudo chflags schg "$folder/.disk_label$suffix"
    done

    [[ -f "$folder/.disk_label.contentDetails" ]] && sudo chflags noschg "$folder/.disk_label.contentDetails"
    [[ -f "$folder/.disk_label.contentDetails" ]] && {
    sudo chflags noschg,nouchg "$folder/.disk_label.contentDetails"
    }
    theoneline="${theoneline/🄳/ [D]}"
    theoneline="${theoneline/🄿/ [P]}"
    theoneline="${theoneline/🅁/ [R]}"
    theoneline="${theoneline/🄱/ [B]}"
    theoneline="${theoneline// / }"
    printf "%s" "$theoneline" > "$tempfolder/disk_label.contentDetails"
    sudo cp "$tempfolder/disk_label.contentDetails" "$folder/.disk_label.contentDetails"
    sudo chflags schg "$folder/.disk_label.contentDetails"
    ((dolockdisklabels)) && sudo chflags schg "$folder/.disk_label.contentDetails"
    hdiutil detach -quiet "${tempfolder}"
    }


    unsetall () {
    local thevarprefix="$1" # prefix for variable names
    if [[ -n $thevarprefix ]]; then
    eval "$(set | sed -nE '/^('"$1"'[^=]*)=.*/s//unset \1/p')"
    eval "$(set | LANG=C sed -nE '/^('"$1"'[^=]*)=.*/s//unset \1/p')"
    fi
    }

    @@ -231,14 +239,34 @@ fixapfsbooter () {
    local patData="^${diskutil_fab1_APFSVolumeGroupID}_Data="
    local patPreboot="^_Preboot="
    local patRecovery="^_Recovery="

    local System_UUID="$diskutil_fab1_APFSVolumeGroupID"

    local roles=""
    roles=$(getapfsroles "$diskutil_fab1_APFSContainerReference")

    local System_UUID=""
    if [[ -n $diskutil_fab1_APFSVolumeGroupID ]]; then
    echo "# APFS Volume Group is $diskutil_fab1_APFSVolumeGroupID"
    IFS=$'\n'
    for thedisk in $(echo "$roles"); do
    if patmatch "$patSys2" <<< "$thedisk"; then
    local thedevice="${thedisk#*=}"
    local diskutil_fabsys_VolumeUUID=""
    getdiskinfo "$thedevice" "diskutil_fabsys_"
    System_UUID="$diskutil_fabsys_VolumeUUID"
    echo "# System Volume UUID is $System_UUID"
    fi
    done
    else
    echo "# No APFS Volume Group"
    fi
    if [[ -z $System_UUID ]]; then
    System_UUID="$diskutil_fab1_VolumeUUID"
    echo "# Assuming System Volume UUID is $System_UUID"
    fi

    for thepass in 0 1; do
    for thedisk in $(getapfsroles "$diskutil_fab1_APFSContainerReference"); do
    IFS=$'\n'
    for thedisk in $(echo "$roles"); do
    if patmatch "$patAll" <<< "$thedisk" ; then
    echo "#================"
    echo "# Doing $thedisk, pass $(( thepass+1 ))"
    @@ -317,9 +345,9 @@ fixapfsbooter () {
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${theline2}"

    echo "# Setting the label to: [${theline1}][${theline2}]"
    sudo find "$thedest" -name '.disk_label*' -exec chflags noschg {} \;
    sudo find "$thedest" -name '.disk_label*' -exec chflags noschg,nouchg {} \;
    sudo cp /tmp/disklabeltemp/.disk_label* "$thedest"
    sudo find "$thedest" -name '.disk_label*' -exec chflags schg {} \;
    ((dolockdisklabels)) && sudo find "$thedest" -name '.disk_label*' -exec chflags schg {} \;
    else
    if [[ -f "$thedest/boot.efi" ]]; then
    echo "# Blessing $thedest/boot.efi"
    @@ -380,12 +408,32 @@ unlockapfsbooter () {
    local patPreboot="^_Preboot="
    local patRecovery="^_Recovery="

    local System_UUID="$diskutil_fab1_APFSVolumeGroupID"
    local roles=""
    roles=$(getapfsroles "$diskutil_fab1_APFSContainerReference")

    local System_UUID=""
    if [[ -n $diskutil_fab1_APFSVolumeGroupID ]]; then
    echo "# APFS Volume Group is $diskutil_fab1_APFSVolumeGroupID"
    IFS=$'\n'
    for thedisk in $(echo "$roles"); do
    if patmatch "$patSys2" <<< "$thedisk"; then
    local thedevice="${thedisk#*=}"
    local diskutil_fabsys_VolumeUUID=""
    getdiskinfo "$thedevice" "diskutil_fabsys_"
    System_UUID="$diskutil_fabsys_VolumeUUID"
    echo "# System Volume UUID is $System_UUID"
    fi
    done
    else
    echo "# No APFS Volume Group"
    fi
    if [[ -z $System_UUID ]]; then
    System_UUID="$diskutil_fab1_VolumeUUID"
    echo "# Assuming System Volume UUID is $System_UUID"
    fi

    for thedisk in $(getapfsroles "$diskutil_fab1_APFSContainerReference"); do
    IFS=$'\n'
    for thedisk in $(echo "$roles"); do
    if patmatch "$patAll" <<< "$thedisk" ; then
    echo "#================"
    echo "# Doing $thedisk"
    @@ -427,7 +475,7 @@ unlockapfsbooter () {
    if [[ -d $thedest ]]; then
    echo "# Unlocking these files:"
    find "$thedest" -name '.disk_label*'
    sudo find "$thedest" -name '.disk_label*' -exec chflags noschg {} \;
    sudo find "$thedest" -name '.disk_label*' -exec chflags noschg,nouchg {} \;
    else
    echo "# Destination does not exist $thedest"
    fi
    @@ -442,7 +490,8 @@ unlockapfsbooter () {
    getvolumeproperty () {
    local slice="$1"
    local property="$2"
    local duinfo="$(diskutil info -plist "$slice" 2> /dev/null)"
    local duinfo=""
    duinfo="$(diskutil info -plist "$slice" 2> /dev/null)"
    eval "$(
    {
    for (( i=0 ; i < 2 ; i++ )); do
    @@ -573,6 +622,7 @@ dumpAllDiskLabels () {

    for thefolder in $( {
    find "$diskutil_dadl_MountPoint" -maxdepth 2 -name "boot.efi*" 2> /dev/null | sed -E '/\/boot.efi.*/s///'
    ls -d "$diskutil_dadl_MountPoint/System/Library/CoreServices"
    ls -d "$diskutil_dadl_MountPoint/"*"/System/Library/CoreServices"
    ls -d "$theblessfolder" "$diskutil_dadl_MountPoint/System/Library/CoreServices" "$diskutil_dadl_MountPoint/EFI/BOOT"
    } 2> /dev/null | sort -u ); do
    @@ -581,7 +631,6 @@ dumpAllDiskLabels () {
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi

    echo "${thefolder} ($version)"
    [[ -f $thefolder/.disk_label.contentDetails ]] && echo "contentDetails: $(cat "$thefolder/.disk_label.contentDetails")" || echo " missing .disk_label.contentDetails"
    [[ -f $thefolder/.disk_label_2x ]] && dump_label "$thefolder/.disk_label_2x" || echo " missing .disk_label_2x"
  2. joevt revised this gist May 23, 2022. 1 changed file with 89 additions and 2 deletions.
    91 changes: 89 additions & 2 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # by joevt Dec 24, 2021
    # by joevt May 23, 2022

    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    @@ -351,6 +351,93 @@ fixapfsbooter () {
    echo "# Done!"
    }

    unlockapfsbooter () {
    # If you use fixapfsbooter to create disk labels for an APFS system, you should probably
    # use this to unlock the disk label files in case the installer doesn't like them.

    theoneapfsmountpoint="$1"

    if [[ -z $theoneapfsmountpoint ]]; then
    echo "#Error: missing parameters"
    return 1
    fi

    local diskutil_fab1_Error=""
    local diskutil_fab1_APFSContainerReference=""
    local diskutil_fab1_APFSVolumeGroupID=""
    local diskutil_fab1_MountPoint=""
    local diskutil_fab1_VolumeUUID=""
    getdiskinfo "$theoneapfsmountpoint" "diskutil_fab1_"
    if [[ -n $diskutil_fab1_Error ]]; then
    echo "# Error: $diskutil_fab1_Error"
    return 1
    fi

    local patAll="^(_|${diskutil_fab1_APFSVolumeGroupID}_System|${diskutil_fab1_APFSVolumeGroupID}_Data|_Preboot|_Recovery)="
    local patSys="^_="
    local patSys2="^${diskutil_fab1_APFSVolumeGroupID}_System="
    local patData="^${diskutil_fab1_APFSVolumeGroupID}_Data="
    local patPreboot="^_Preboot="
    local patRecovery="^_Recovery="

    local System_UUID="$diskutil_fab1_APFSVolumeGroupID"
    if [[ -z $System_UUID ]]; then
    System_UUID="$diskutil_fab1_VolumeUUID"
    fi

    for thedisk in $(getapfsroles "$diskutil_fab1_APFSContainerReference"); do
    if patmatch "$patAll" <<< "$thedisk" ; then
    echo "#================"
    echo "# Doing $thedisk"

    local thedevice="${thedisk#*=}"
    diskutil mount "$thedevice" > /dev/null 2>&1
    getdiskinfo "$thedevice" "diskutil_fab2_"
    if [[ -z "$diskutil_fab2_MountPoint" ]]; then
    echo "# Could not mount"
    else
    local issource=0

    if [[ "$diskutil_fab2_MountPoint" == "$diskutil_fab1_MountPoint" ]]; then
    issource=1
    fi

    local thedest=""

    if patmatch "$patSys" <<< "$thedisk"; then
    if ((issource)); then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    fi
    elif patmatch "$patSys2" <<< "$thedisk"; then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif patmatch "$patData" <<< "$thedisk"; then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif patmatch "$patPreboot" <<< "$thedisk"; then
    thedest="$diskutil_fab2_MountPoint/$System_UUID/System/Library/CoreServices"
    if [[ ! -d $thedest ]]; then
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_VolumeUUID/System/Library/CoreServices"
    fi
    elif patmatch "$patRecovery" <<< "$thedisk"; then
    thedest="$diskutil_fab2_MountPoint/$System_UUID"
    if [[ ! -d $thedest ]]; then
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_VolumeUUID"
    fi
    fi

    if [[ -d $thedest ]]; then
    echo "# Unlocking these files:"
    find "$thedest" -name '.disk_label*'
    sudo find "$thedest" -name '.disk_label*' -exec chflags noschg {} \;
    else
    echo "# Destination does not exist $thedest"
    fi
    fi # if mount
    fi # if the disk
    done # for thedisk

    echo "#================"
    echo "# Done!"
    }

    getvolumeproperty () {
    local slice="$1"
    @@ -441,7 +528,7 @@ mounthfsimage () {
    printf("device=\"%s\"\nvolume_kind=\"%s\"\n", $f->[0]->{"dev-entry"}, $f->[0]->{"volume-kind"})
    '
    )"
    if [[ $volume_kind = "hfs" ]]; then
    if [[ -z $volume_kind ]] || [[ $volume_kind = "hfs" ]]; then
    local volume=""
    local slice="${device/\/dev\//}"
    volume="$(getvolumename "$slice")"
  3. joevt revised this gist Dec 24, 2021. 1 changed file with 35 additions and 15 deletions.
    50 changes: 35 additions & 15 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # by joevt Nov 30, 2021
    # by joevt Dec 24, 2021

    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    @@ -176,6 +176,10 @@ unsetall () {
    fi
    }

    patmatch () {
    # substitute for [[ =~ ]] for Mac OS X 10.4
    perl -0777 -ne '<>; exit !( $_ =~ /'"$1"'/ )'
    }

    fixapfsbooter () {
    # Use Catalina for best results.
    @@ -235,7 +239,7 @@ fixapfsbooter () {

    for thepass in 0 1; do
    for thedisk in $(getapfsroles "$diskutil_fab1_APFSContainerReference"); do
    if [[ $thedisk =~ $patAll ]]; then
    if patmatch "$patAll" <<< "$thedisk" ; then
    echo "#================"
    echo "# Doing $thedisk, pass $(( thepass+1 ))"

    @@ -254,22 +258,22 @@ fixapfsbooter () {
    local theletter=""
    local thedest=""

    if [[ $thedisk =~ $patSys ]]; then
    if patmatch "$patSys" <<< "$thedisk"; then
    if ((issource)); then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    fi
    elif [[ $thedisk =~ $patSys2 ]]; then
    elif patmatch "$patSys2" <<< "$thedisk"; then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif [[ $thedisk =~ $patData ]]; then
    elif patmatch "$patData" <<< "$thedisk"; then
    theletter="🄳"
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif [[ $thedisk =~ $patPreboot ]]; then
    elif patmatch "$patPreboot" <<< "$thedisk"; then
    theletter="🄿"
    thedest="$diskutil_fab2_MountPoint/$System_UUID/System/Library/CoreServices"
    if [[ ! -d $thedest ]]; then
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_VolumeUUID/System/Library/CoreServices"
    fi
    elif [[ $thedisk =~ $patRecovery ]]; then
    elif patmatch "$patRecovery" <<< "$thedisk"; then
    theletter="🅁"
    thedest="$diskutil_fab2_MountPoint/$System_UUID"
    if [[ ! -d $thedest ]]; then
    @@ -351,7 +355,19 @@ fixapfsbooter () {
    getvolumeproperty () {
    local slice="$1"
    local property="$2"
    eval "$(diskutil info -plist "$slice" | plutil -p - | sed -nE '/^ *"'"$property"'" => (.*)/s//echo \1/p')"
    local duinfo="$(diskutil info -plist "$slice" 2> /dev/null)"
    eval "$(
    {
    for (( i=0 ; i < 2 ; i++ )); do
    if patmatch "Disk Utility Tool" <<< "$duinfo"; then
    diskutil info "$slice" | perl -ne 'while (<>) { if (/ +([^:]+): +"?(.*?)"?$/) { $name = $1; $value = $2; $name =~ s/ //g; print "\"" . $name . "\" => \"" . $value . "\"\n" } }'
    break
    else
    printf "%s" "$duinfo" | plutil -p - 2> /dev/null && break || duinfo="Disk Utility Tool"
    fi
    done
    } | sed -nE '/^ *"'"$property"'" => (.*)/s//echo \1/p'
    )"
    }


    @@ -363,18 +379,22 @@ getvolumename () {
    mountEFIpartitions () {
    IFS=$'\n'
    local diskinfo=""
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +EFI (\xe2\x81\xa8)?(.*[^ \xa9])?(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +EFI (\xe2\x81\xa8)?(.*[^ \xa9])?(\xe2\x81\xa9)? +[0-9.]+ [^ ]?[Bi] +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume=""
    volume="$(getvolumename "$slice")"
    if [[ -z $volume ]]; then
    volume="EFI" # Mac OS X 10.4.11 doesn't load EFI volume name
    fi
    #echo mountpartition "_msdos" "$slice" "$volume"
    mountpartition "_msdos" "$slice" "$volume" > /dev/null
    done
    }


    mountRecoveryHDpartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_Boot (\xe2\x81\xa8)?(Recovery HD)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_Boot (\xe2\x81\xa8)?(Recovery HD)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?[Bi] +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume=""
    volume="$(getvolumename "$slice")"
    @@ -385,7 +405,7 @@ mountRecoveryHDpartitions() {

    mountRecoveryPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Recovery)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Recovery)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?[Bi] +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume=""
    volume="$(getvolumename "$slice")"
    @@ -396,7 +416,7 @@ mountRecoveryPartitions() {

    mountPrebootPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Preboot)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Preboot)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?[Bi] +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume=""
    volume="$(getvolumename "$slice")"
    @@ -491,7 +511,7 @@ makeLabelCommands () {
    # Only includes Apple_HFS and Apple_Boot partitions.
    IFS=$'\n'
    local thefolder=""
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_[HFSBoot]* (\xe2\x81\xa8)?([^ ].*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_[HFSBoot]* (\xe2\x81\xa8)?([^ ].*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?[Bi] +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume=""
    volume="$(getvolumename "$slice")"
    @@ -584,7 +604,7 @@ getdiskinfo () {
    showdiskinfo () {
    local thedisk="$1" # the disk you want info for (either a mountpoint like "/" or a device "disk0s1")
    local thevarprefix="$2" # prefix for variable names
    diskutil info -plist "$thedisk" | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'"$thevarprefix"'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }'
    diskutil info -plist "$thedisk" 2> /dev/null | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'"$thevarprefix"'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }'
    }


    @@ -598,7 +618,7 @@ getapfsroles () {
    '
    ); do
    diskutil_role_APFSVolumeGroupID=""
    if [[ $theapfsvolume =~ $patVolumeGroup ]]; then
    if patmatch "$patVolumeGroup" <<< "$theapfsvolume"; then
    getdiskinfo "${theapfsvolume#*=}" "diskutil_role_"
    fi
    echo "${diskutil_role_APFSVolumeGroupID}_${theapfsvolume}"
  4. joevt revised this gist Dec 1, 2021. 1 changed file with 17 additions and 4 deletions.
    21 changes: 17 additions & 4 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # by joevt Nov 27, 2021
    # by joevt Nov 30, 2021

    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    @@ -84,7 +84,17 @@ mountpartition() {


    makemultilinedisklabel () {
    if (( $# != 2 )); then
    echo "# error: not enough arguments" 1>&2
    echo "# usage: makemultilinedisklabel destinationpath disklabellines" 1>&2
    return 1
    fi
    local folder="$1"
    if [[ ! -d $folder ]]; then
    echo '# error: "'"$folder"' is not a folder' 1>&2
    echo "# usage: makemultilinedisklabel destinationpath disklabellines" 1>&2
    return 1
    fi
    local lines="$2"
    local alllines=""
    local alllines2x=""
    @@ -427,9 +437,12 @@ getblessinfo () {
    local mountpoint="$1"
    local thevarprefix="$2"
    unsetall "$thevarprefix"
    eval "$(directbless -plist --info "$mountpoint" | plutil -convert json -o - - | perl -e '
    use JSON::PP; my $f = decode_json (<>)->{"Finder Info"};
    printf("'"$thevarprefix"'theblessfolder=\"%s\"\n'"$thevarprefix"'theblessfile=\"%s\"\n'"$thevarprefix"'theblessopen=\"%s\"\n", $f->[0]->{"Path"}, $f->[1]->{"Path"}, $f->[2]->{"Path"})')"
    eval "$(
    directbless -plist --info "$mountpoint" 2> /dev/null | plutil -convert json -o - - | perl -e '
    use JSON::PP; my $f = decode_json (<>)->{"Finder Info"};
    printf("'"$thevarprefix"'theblessfolder=\"%s\"\n'"$thevarprefix"'theblessfile=\"%s\"\n'"$thevarprefix"'theblessopen=\"%s\"\n", $f->[0]->{"Path"}, $f->[1]->{"Path"}, $f->[2]->{"Path"})
    ' 2> /dev/null
    )"
    }


  5. joevt revised this gist Nov 28, 2021. 1 changed file with 60 additions and 10 deletions.
    70 changes: 60 additions & 10 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,10 @@
    #!/bin/bash
    # by joevt Oct 12, 2021
    # by joevt Nov 27, 2021

    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    if [[ -d /System/Library/PrivateFrameworks/APFS.framework/Versions/A/APFS ]]; then
    if [[ ! -f "$directbless" ]]; then
    if [[ -d /System/Library/PrivateFrameworks/APFS.framework/Versions/A ]]; then
    if [[ ! -f "$directblesscmd" ]]; then
    echo "# Download and build bless from https://github.com/joevt/bless , then update the path of directbless defined in DiskUtil.sh"
    else
    usedirectbless=1
    @@ -37,9 +37,10 @@ convert_label () {
    thedest="$thelabel.tiff"
    fi

    local contents=""
    contents=$(xxd -p "$thelabel")
    width=$((0x${contents:2:4}))
    height=$((0x${contents:6:4}))
    local width=$((0x${contents:2:4}))
    local height=$((0x${contents:6:4}))
    echo "
    4949 2a00 1800 0000 d002 0000 0a00 0000 d002 0000 0a00 0000 0d00 fe00 0400 0100
    0000 0000 0000 0001 0400 0100 0000 $(le width) 0101 0400 0100 0000 $(le height) 0201
    @@ -54,6 +55,7 @@ convert_label () {
    " | xxd -p -r > "$thedest"
    }


    # mount a partition
    mountpartition() {
    local mounttype=$1
    @@ -86,8 +88,19 @@ makemultilinedisklabel () {
    local lines="$2"
    local alllines=""
    local alllines2x=""
    local tempfolder0=""
    local tempfolder=""
    tempfolder="$(mktemp -d)"
    tempfolder0="$(mktemp -d)"
    # do the blessing on a temporary disk image so it doesn't do apfs stuff like copy the disk label to preboot of the current system
    tempfolder="$(hdiutil create -volname disklabeltmp -size 600k -fs HFS+ -attach "$tempfolder0/tmp.dmg" | perl -nE 'if (/\/dev\/disk[0-9]+s[0-9]+[^\t]*\tApple_HFS[^\t]*\t(.*)/) { print $1 }')"
    if [[ -z $tempfolder ]]; then
    echo "# error creating temporary disk image" 1>&2
    return 1
    fi
    if [[ ! -d $tempfolder ]]; then
    echo "# error getting temporary disk image mount point: $tempfolder" 1>&2
    return 1
    fi

    IFS=$'\n'
    local linenum=0
    @@ -142,6 +155,7 @@ makemultilinedisklabel () {
    printf "%s" "$theoneline" > "$tempfolder/disk_label.contentDetails"
    sudo cp "$tempfolder/disk_label.contentDetails" "$folder/.disk_label.contentDetails"
    sudo chflags schg "$folder/.disk_label.contentDetails"
    hdiutil detach -quiet "${tempfolder}"
    }


    @@ -258,8 +272,12 @@ fixapfsbooter () {
    if ((issource)); then
    echo "# Skipping icon copy"
    elif [[ -f "$iconsource" ]]; then
    if [[ -L "$diskutil_fab2_MountPoint/.VolumeIcon.icns" ]]; then
    echo "# Removing icon sym link"
    sudo rm "$diskutil_fab2_MountPoint/.VolumeIcon.icns"
    fi
    echo "# Doing icon copy"
    sudo cp "$iconsource" "$diskutil_fab2_MountPoint" || echo "# Error copying icon"
    sudo cp -p "$iconsource" "$diskutil_fab2_MountPoint" || echo "# Error copying icon"
    else
    echo "# No icon to copy"
    fi
    @@ -377,6 +395,34 @@ mountPrebootPartitions() {
    }


    mounthfsimage () {
    # macOS doesn't support mounting HFS anymore. To get around that,
    # this command uses https://github.com/joevt/fusehfs.
    # Useful for mounting SheepShaver.app disk image.
    local theimage="$1"

    theresult=$(hdiutil attach "$theimage" -readonly -nomount -noverify -noautofsck -plist)
    if [[ -n $theresult ]]; then
    local device=""
    local volume_kind=""
    eval "$(
    plutil -convert json -o - - <<< "$theresult" | perl -e '
    use JSON::PP; my $f = decode_json (<>)->{"system-entities"};
    printf("device=\"%s\"\nvolume_kind=\"%s\"\n", $f->[0]->{"dev-entry"}, $f->[0]->{"volume-kind"})
    '
    )"
    if [[ $volume_kind = "hfs" ]]; then
    local volume=""
    local slice="${device/\/dev\//}"
    volume="$(getvolumename "$slice")"
    mountpartition "_fusefs_hfs" "$slice" "$volume" # > /dev/null
    else
    echo "# unexpected volume kind '$volume_kind'"
    fi
    fi
    }


    getblessinfo () {
    local mountpoint="$1"
    local thevarprefix="$2"
    @@ -405,7 +451,11 @@ dumpAllDiskLabels () {
    theblessfolder="$(dirname "$theblessfile")"
    fi

    for thefolder in $( { find "$diskutil_dadl_MountPoint" -maxdepth 2 -name "boot.efi" 2> /dev/null | sed -E '/\/boot.efi$/s///'; ls -d "$diskutil_dadl_MountPoint/"*"/System/Library/CoreServices"; ls -d "$theblessfolder" "$diskutil_dadl_MountPoint/System/Library/CoreServices" "$diskutil_dadl_MountPoint/EFI/BOOT" ; } 2> /dev/null | sort -u ); do
    for thefolder in $( {
    find "$diskutil_dadl_MountPoint" -maxdepth 2 -name "boot.efi*" 2> /dev/null | sed -E '/\/boot.efi.*/s///'
    ls -d "$diskutil_dadl_MountPoint/"*"/System/Library/CoreServices"
    ls -d "$theblessfolder" "$diskutil_dadl_MountPoint/System/Library/CoreServices" "$diskutil_dadl_MountPoint/EFI/BOOT"
    } 2> /dev/null | sort -u ); do
    local version=""
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    @@ -453,7 +503,7 @@ makeLabelCommands () {

    # Scan the usual places first
    IFS=$'\n'
    for thefolder in $(find /Volumes/*/System/Library/CoreServices /Volumes/*/EFI/BOOT -maxdepth 0); do
    for thefolder in $({ find /Volumes/*/System/Library/CoreServices -maxdepth 0 || true ; find /Volumes/*/EFI/BOOT -maxdepth 0 || true ; } 2> /dev/null); do
    local volume=""
    local version=""
    volume="${thefolder/\/System\/Library\/CoreServices/}"
    @@ -663,7 +713,7 @@ setfinderinfoflag () {
    newfinderinfo=${thefinderinfo:0:$thechar}$( printf "%x" $(( ${thefinderinfo:$thechar:1} & (~(1<<(thebit))) | (thevalue<<(thebit)) )) )${thefinderinfo:$((thechar+1))}
    if [[ "$newfinderinfo" != "$thefinderinfo" ]]; then
    echo "# modifying ${thedescription}FinderInfo $newfinderinfo $thepath"
    xattr -wx com.apple.FinderInfo "$newfinderinfo" "$thepath"
    sudo xattr -wx com.apple.FinderInfo "$newfinderinfo" "$thepath"
    else
    echo "# unchanged ${thedescription}FinderInfo $newfinderinfo $thepath"
    fi
  6. joevt revised this gist Oct 13, 2021. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # by joevt Oct 13, 2021
    # by joevt Oct 12, 2021

    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    @@ -46,7 +46,7 @@ convert_label () {
    0300 0100 0000 0800 0000 0301 0300 0100 0000 0100 0000 0601 0300 0100 0000 0000
    0000 1101 0400 0100 0000 ba00 0000 1501 0300 0100 0000 0100 0000 1601 0400 0100
    0000 $(le width) 1701 0400 0100 0000 $(le $((width * height))) 1a01 0500 0100 0000 0800 0000 1b01
    0500 0100 0000 1000 0000 2801 0300 0100 0000 0200 0000 0000 0000 00
    0500 0100 0000 1000 0000 2801 0300 0100 0000 0200 0000 0000 0000
    $(echo "${contents:10}" | xxd -p -r | LANG=C tr -C \
    '\0\366\367\52\370\371\125\372\373\200\374\375\253\376\377\326' '\0' | LANG=C tr \
    '\0\366\367\52\370\371\125\372\373\200\374\375\253\376\377\326' \
  7. joevt revised this gist Oct 13, 2021. 1 changed file with 6 additions and 4 deletions.
    10 changes: 6 additions & 4 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # by joevt Oct 12, 2021
    # by joevt Oct 13, 2021

    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    @@ -22,7 +22,8 @@ fi
    # dump disk_label file
    dump_label () { local contents; contents=$(xxd -p -c99999 "$1"); echo "${contents:10}" | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }

    le () { thenum=$(printf "%08x" $(($1))); printf ${thenum:6:2}${thenum:4:2}${thenum:2:2}${thenum:0:2} }
    # convert 4 byte number to little-endian
    le () { local n; n=$(printf "%08x" $(($1))); printf "%s" "${n:6:2}${n:4:2}${n:2:2}${n:0:2}"; }

    #convert disk_lbel to tiff file
    convert_label () {
    @@ -46,8 +47,8 @@ convert_label () {
    0000 1101 0400 0100 0000 ba00 0000 1501 0300 0100 0000 0100 0000 1601 0400 0100
    0000 $(le width) 1701 0400 0100 0000 $(le $((width * height))) 1a01 0500 0100 0000 0800 0000 1b01
    0500 0100 0000 1000 0000 2801 0300 0100 0000 0200 0000 0000 0000 00
    $(echo ${contents:10} | xxd -p -r | tr -C \
    '\0\366\367\52\370\371\125\372\373\200\374\375\253\376\377\326' '\0' | tr \
    $(echo "${contents:10}" | xxd -p -r | LANG=C tr -C \
    '\0\366\367\52\370\371\125\372\373\200\374\375\253\376\377\326' '\0' | LANG=C tr \
    '\0\366\367\52\370\371\125\372\373\200\374\375\253\376\377\326' \
    '\0\021\042\63\104\125\146\167\210\231\252\273\314\335\356\377' | xxd -p)
    " | xxd -p -r > "$thedest"
    @@ -470,6 +471,7 @@ makeLabelCommands () {
    clearOpenFoldersAll () {
    # Clear open folder list of hfs partitions (finderinfo[2] in bless --info).
    # If you have an HFS+ disk that has folders that open when you mount them (such as an installer), then this will stop that from happening.
    IFS=$'\n'
    clearOpenFolders $(getallhfsdisks)
    }

  8. joevt revised this gist Oct 12, 2021. 1 changed file with 31 additions and 1 deletion.
    32 changes: 31 additions & 1 deletion DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # by joevt Aug 5, 2021
    # by joevt Oct 12, 2021

    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    @@ -22,6 +22,36 @@ fi
    # dump disk_label file
    dump_label () { local contents; contents=$(xxd -p -c99999 "$1"); echo "${contents:10}" | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }

    le () { thenum=$(printf "%08x" $(($1))); printf ${thenum:6:2}${thenum:4:2}${thenum:2:2}${thenum:0:2} }

    #convert disk_lbel to tiff file
    convert_label () {
    local thelabel="$1"
    local thedest="$2"
    if [[ ! -f $thelabel ]]; then
    printf '# Disk label "%s" does not exist.\n' "$thelabel"
    return 1
    fi
    if [[ -z $thedest ]]; then
    thedest="$thelabel.tiff"
    fi

    contents=$(xxd -p "$thelabel")
    width=$((0x${contents:2:4}))
    height=$((0x${contents:6:4}))
    echo "
    4949 2a00 1800 0000 d002 0000 0a00 0000 d002 0000 0a00 0000 0d00 fe00 0400 0100
    0000 0000 0000 0001 0400 0100 0000 $(le width) 0101 0400 0100 0000 $(le height) 0201
    0300 0100 0000 0800 0000 0301 0300 0100 0000 0100 0000 0601 0300 0100 0000 0000
    0000 1101 0400 0100 0000 ba00 0000 1501 0300 0100 0000 0100 0000 1601 0400 0100
    0000 $(le width) 1701 0400 0100 0000 $(le $((width * height))) 1a01 0500 0100 0000 0800 0000 1b01
    0500 0100 0000 1000 0000 2801 0300 0100 0000 0200 0000 0000 0000 00
    $(echo ${contents:10} | xxd -p -r | tr -C \
    '\0\366\367\52\370\371\125\372\373\200\374\375\253\376\377\326' '\0' | tr \
    '\0\366\367\52\370\371\125\372\373\200\374\375\253\376\377\326' \
    '\0\021\042\63\104\125\146\167\210\231\252\273\314\335\356\377' | xxd -p)
    " | xxd -p -r > "$thedest"
    }

    # mount a partition
    mountpartition() {
  9. joevt revised this gist Aug 6, 2021. 1 changed file with 125 additions and 41 deletions.
    166 changes: 125 additions & 41 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,19 @@
    #!/bin/bash
    # by joevt Jan 31, 2021
    # by joevt Aug 5, 2021

    directbless="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    alias directbless='"$directbless"'
    if [[ ! -f "$directbless" ]]; then
    echo "# Download and build bless from https://github.com/joevt/bless , then update the path of directbless defined in DiskUtil.sh"
    directblesscmd="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    usedirectbless=0
    if [[ -d /System/Library/PrivateFrameworks/APFS.framework/Versions/A/APFS ]]; then
    if [[ ! -f "$directbless" ]]; then
    echo "# Download and build bless from https://github.com/joevt/bless , then update the path of directbless defined in DiskUtil.sh"
    else
    usedirectbless=1
    fi
    fi
    if ((usedirectbless)); then
    directbless=$directblesscmd
    alias directbless='"$directbless"'
    else
    directbless=bless
    alias directbless=bless
    fi
    @@ -54,8 +63,6 @@ makemultilinedisklabel () {
    local theline=""
    local theoneline=""
    for theline in $(echo "$lines"); do
    #echo "doing line: \"$theline\""
    #echo sudo bless --folder "$folder" --label "$theline"
    sudo bless --folder "$tempfolder" --label "$theline" 2> /dev/null
    if (( linenum )); then
    alllines+="$(dump_label "$tempfolder/.disk_label" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    @@ -93,8 +100,6 @@ makemultilinedisklabel () {
    [[ -f "$folder/.disk_label$suffix" ]] && sudo chflags noschg "$folder/.disk_label$suffix"
    sudo cp "$tempfolder/disk_label$suffix" "$folder/.disk_label$suffix"
    sudo chflags schg "$folder/.disk_label$suffix"
    #sudo bless --folder "$folder" --labelfile "$tempfolder/disk_label$suffix"
    #dump_label "$folder/.disk_label$suffix"
    done

    [[ -f "$folder/.disk_label.contentDetails" ]] && sudo chflags noschg "$folder/.disk_label.contentDetails"
    @@ -255,7 +260,7 @@ fixapfsbooter () {
    else
    if [[ -f "$thedest/boot.efi" ]]; then
    echo "# Blessing $thedest/boot.efi"
    if [[ -f "$directbless" ]]; then
    if ((usedirectbless)); then
    sudo "$directbless" --folder "$thedest" --file "$thedest/boot.efi"
    else
    if [[ -z $theletter ]]; then
    @@ -299,7 +304,7 @@ getvolumename () {
    mountEFIpartitions () {
    IFS=$'\n'
    local diskinfo=""
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +EFI (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +EFI (\xe2\x81\xa8)?(.*[^ \xa9])?(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume=""
    volume="$(getvolumename "$slice")"
    @@ -432,12 +437,17 @@ makeLabelCommands () {
    }


    clearOpenFolders () {
    clearOpenFoldersAll () {
    # Clear open folder list of hfs partitions (finderinfo[2] in bless --info).
    # If you have an HFS+ disk that has folders that open when you mount them (such as an installer), then this will stop that from happening.
    IFS=$'\n'
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_HFS (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    clearOpenFolders $(getallhfsdisks)
    }


    clearOpenFolders () {
    while (($#)); do
    local slice="$1"
    shift
    local volume=""
    volume="$(getvolumename "$slice")"
    local mountpoint=""
    @@ -449,7 +459,19 @@ clearOpenFolders () {
    getblessinfo "$mountpoint"
    if [[ -n $theblessopen ]]; then
    echo "Clearing open folder list"
    sudo "$directbless" --folder "$theblessfolder" --file "$theblessfile"
    if [[ -n $theblessfolder ]]; then
    if [[ -n $theblessfile ]]; then
    sudo "$directbless" --folder "$theblessfolder" --file "$theblessfile"
    else
    sudo "$directbless" --folder "$theblessfolder"
    fi
    else
    if [[ -n $theblessfile ]]; then
    sudo "$directbless" --mount "$mountpoint" --file "$theblessfile" --openfolder ""
    else
    sudo "$directbless" --unbless "$mountpoint"
    fi
    fi
    fi
    done
    }
    @@ -529,62 +551,124 @@ setbootername () {
    }


    doperlonmounteddisks () {
    diskutil list -plist | plutil -convert json -o - - | perl -e '
    doperlondisks () {
    local thefilter="$1"
    local theperl="$2"
    {
    if [[ -z $thefilter ]]; then
    diskutil list -plist
    else
    diskutil list -plist "$thefilter"
    fi
    } | plutil -convert json -o - - | perl -e '
    use JSON::PP; my $disks = decode_json (<>)->{AllDisksAndPartitions};
    foreach my $disk (@$disks) {
    foreach my $type ("APFSVolumes","Partitions") {
    foreach my $part (@{$disk->{$type}}) {
    if (exists $part->{MountPoint}) {
    '"$1"'
    }
    '"$theperl"'
    }
    }
    }
    '
    }


    doperlonmounteddisks () {
    doperlondisks "$1" '
    if (exists $part->{MountPoint}) {
    '"$2"'
    }
    '
    }


    getallmounteddisks () {
    # not all disks are mounted at /Volumes so use diskutil to find them
    if [[ "$1" == "-d" ]]; then
    doperlonmounteddisks 'print $part->{DeviceIdentifier} . ":" . $part->{MountPoint} . "\n";'
    doperlonmounteddisks "" 'print $part->{DeviceIdentifier} . ":" . $part->{MountPoint} . "\n";'
    else
    doperlonmounteddisks 'print $part->{MountPoint} . "\n";'
    doperlonmounteddisks "" 'print $part->{MountPoint} . "\n";'
    fi
    }


    fixcustomiconflag () {
    local thefolder="$1"
    # if the folder is a mount point then the icon should be in datafork of ".VolumeIcon.icns"
    # otherwise the icon should be in a icns resource in "Icon\n"
    getalldisks () {
    doperlondisks "$1" 'print $part->{DeviceIdentifier} . "\n";'
    }


    getallhfsdisks () {
    doperlondisks "$1" '
    if ($part->{Content} eq "Apple_HFS") {
    print $part->{DeviceIdentifier} . "\n";
    }
    '
    }


    getallefidisks () {
    doperlondisks "$1" '
    if ($part->{Content} eq "EFI") {
    print $part->{DeviceIdentifier} . "\n";
    }
    '
    }


    setfinderinfoflag () {
    local thepath="$1"
    local thechar="$2"
    local thebit="$3"
    local thevalue="$4"
    local thefinderinfo=""
    local newfinderinfo=""
    thefinderinfo=$(xattr -px com.apple.FinderInfo "$thefolder" 2> /dev/null | xxd -p -r | xxd -p -c 32)
    local thedescription=""
    thefinderinfo=$(xattr -px com.apple.FinderInfo "$thepath" 2> /dev/null | xxd -p -r | xxd -p -c 32)
    if [[ -z "$thefinderinfo" ]]; then
    newfinderinfo="0000000000000000040000000000000000000000000000000000000000000000"
    echo "# creating FinderInfo $newfinderinfo $thefolder"
    else
    newfinderinfo=${thefinderinfo:0:17}$(printf "%x" $((${thefinderinfo:17:1} | 4)) )${thefinderinfo:18}
    if [[ "$newfinderinfo" != "$thefinderinfo" ]]; then
    echo "# modifying FinderInfo $newfinderinfo $thefolder"
    else
    echo "# unchanged FinderInfo $newfinderinfo $thefolder"
    fi
    thefinderinfo="0000000000000000000000000000000000000000000000000000000000000000"
    thedescription="nonexistant "
    fi

    newfinderinfo=${thefinderinfo:0:$thechar}$( printf "%x" $(( ${thefinderinfo:$thechar:1} & (~(1<<(thebit))) | (thevalue<<(thebit)) )) )${thefinderinfo:$((thechar+1))}
    if [[ "$newfinderinfo" != "$thefinderinfo" ]]; then
    xattr -wx com.apple.FinderInfo "$newfinderinfo" "$thefolder"
    fi
    echo "# modifying ${thedescription}FinderInfo $newfinderinfo $thepath"
    xattr -wx com.apple.FinderInfo "$newfinderinfo" "$thepath"
    else
    echo "# unchanged ${thedescription}FinderInfo $newfinderinfo $thepath"
    fi
    }
    getfinderinfoflag () {
    local thepath="$1"
    local thechar="$2"
    local thebit="$3"
    local thefinderinfo=""
    thefinderinfo=$(xattr -px com.apple.FinderInfo "$thepath" 2> /dev/null | xxd -p -r | xxd -p -c 32)
    echo $(( ( 0x0${thefinderinfo:$thechar:1} >> thebit ) & 1 ))
    }
    setfoldercustomicon () {
    # if the folder is a mount point then the icon should be in datafork of ".VolumeIcon.icns"
    # otherwise the icon should be in a icns resource in "Icon\n"
    setfinderinfoflag "$1" 17 2 1
    }
    isfileinvisible () {
    getfinderinfoflag "$1" 16 2
    }
    setfilevisible () {
    setfinderinfoflag "$1" 16 2 0
    }
    setfileinvisible () {
    setfinderinfoflag "$1" 16 2 1
    }
    fixcustomiconflagofallvolumes () {
    IFS=$'\n'
    for themount in $(getallmounteddisks); do
    if [[ -f "$themount/.VolumeIcon.icns" ]]; then
    fixcustomiconflag "$themount"
    setfoldercustomicon "$themount"
    fi
    done
    }
  10. joevt revised this gist Feb 1, 2021. 1 changed file with 6 additions and 5 deletions.
    11 changes: 6 additions & 5 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,12 @@
    #!/bin/bash
    # by joevt Jan 30, 2021

    directbless="/Volumes/Work/Programming/XcodeProjects/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    alias directbless=\""$directbless"\"
    # by joevt Jan 31, 2021

    directbless="/Volumes/Work/Programming/XcodeProjects/bless/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    alias directbless='"$directbless"'
    if [[ ! -f "$directbless" ]]; then
    echo "# Download and build bless from https://github.com/joevt/bless , then update the path of directbless defined in DiskUtil.sh"
    directbless=bless
    alias directbless=bless
    fi


    @@ -102,7 +103,7 @@ makemultilinedisklabel () {
    theoneline="${theoneline/🅁/ [R]}"
    theoneline="${theoneline/🄱/ [B]}"
    theoneline="${theoneline// / }"
    printf "$theoneline" > "$tempfolder/disk_label.contentDetails"
    printf "%s" "$theoneline" > "$tempfolder/disk_label.contentDetails"
    sudo cp "$tempfolder/disk_label.contentDetails" "$folder/.disk_label.contentDetails"
    sudo chflags schg "$folder/.disk_label.contentDetails"
    }
  11. joevt revised this gist Jan 31, 2021. 1 changed file with 5 additions and 3 deletions.
    8 changes: 5 additions & 3 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,8 @@
    #!/bin/bash
    # by joevt Jan 15, 2021
    # by joevt Jan 30, 2021

    directbless="/Volumes/Work/Programming/XcodeProjects/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"
    alias directbless=\""$directbless"\"

    if [[ ! -f "$directbless" ]]; then
    echo "# Download and build bless from https://github.com/joevt/bless , then update the path of directbless defined in DiskUtil.sh"
    @@ -100,6 +101,7 @@ makemultilinedisklabel () {
    theoneline="${theoneline/🄿/ [P]}"
    theoneline="${theoneline/🅁/ [R]}"
    theoneline="${theoneline/🄱/ [B]}"
    theoneline="${theoneline// / }"
    printf "$theoneline" > "$tempfolder/disk_label.contentDetails"
    sudo cp "$tempfolder/disk_label.contentDetails" "$folder/.disk_label.contentDetails"
    sudo chflags schg "$folder/.disk_label.contentDetails"
    @@ -342,7 +344,7 @@ getblessinfo () {
    local mountpoint="$1"
    local thevarprefix="$2"
    unsetall "$thevarprefix"
    eval "$(bless -plist --info "$mountpoint" | plutil -convert json -o - - | perl -e '
    eval "$(directbless -plist --info "$mountpoint" | plutil -convert json -o - - | perl -e '
    use JSON::PP; my $f = decode_json (<>)->{"Finder Info"};
    printf("'"$thevarprefix"'theblessfolder=\"%s\"\n'"$thevarprefix"'theblessfile=\"%s\"\n'"$thevarprefix"'theblessopen=\"%s\"\n", $f->[0]->{"Path"}, $f->[1]->{"Path"}, $f->[2]->{"Path"})')"
    }
    @@ -446,7 +448,7 @@ clearOpenFolders () {
    getblessinfo "$mountpoint"
    if [[ -n $theblessopen ]]; then
    echo "Clearing open folder list"
    sudo bless --folder "$theblessfolder" --file "$theblessfile"
    sudo "$directbless" --folder "$theblessfolder" --file "$theblessfile"
    fi
    done
    }
  12. joevt revised this gist Jan 15, 2021. 1 changed file with 274 additions and 118 deletions.
    392 changes: 274 additions & 118 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,15 @@
    # by joevt Dec 30, 2020
    #!/bin/bash
    # by joevt Jan 15, 2021

    directbless="/Volumes/Work/Programming/XcodeProjects/bless-204.40.27 joevt/DerivedData/bless/Build/Products/Debug/bless"

    if [[ ! -f "$directbless" ]]; then
    echo "# Download and build bless from https://github.com/joevt/bless , then update the path of directbless defined in DiskUtil.sh"
    fi


    # dump disk_label file
    dump_label () { local contents=$(xxd -p -c99999 "$1"); echo ${contents:10} | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }
    dump_label () { local contents; contents=$(xxd -p -c99999 "$1"); echo "${contents:10}" | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }


    # mount a partition
    @@ -36,21 +44,25 @@ makemultilinedisklabel () {
    local lines="$2"
    local alllines=""
    local alllines2x=""
    local tempfolder="$(mktemp -d)"
    local tempfolder=""
    tempfolder="$(mktemp -d)"

    IFS=$'\n'
    local linenum=0
    local theline=""
    local theoneline=""
    for theline in $(echo "$lines"); do
    #echo "doing line: \"$theline\""
    #echo sudo bless --folder "$folder" --label "$theline"
    sudo bless --folder "$tempfolder" --label "$theline" 2> /dev/null
    if (( $linenum )); then
    if (( linenum )); then
    alllines+="$(dump_label "$tempfolder/.disk_label" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    alllines2x+="$(dump_label "$tempfolder/.disk_label_2x" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    theoneline+=" $theline"
    else
    alllines+="$(dump_label "$tempfolder/.disk_label")"$'\n'
    alllines2x+="$(dump_label "$tempfolder/.disk_label_2x")"$'\n'
    theoneline="$theline"
    fi
    ((linenum++))
    done
    @@ -60,8 +72,10 @@ makemultilinedisklabel () {
    for suffix in "" "_2x"; do
    [[ -z $suffix ]] && thelines="$alllines" || thelines="$alllines2x"

    local linewidths="$(echo "${thelines}" | tr '0-9a-f' '.' | sort -ur)"
    local maxlinewidth=$(echo "$linewidths" | sed -n '1p')
    local linewidths=""
    local maxlinewidth=""
    linewidths="$(echo "${thelines}" | tr '0-9a-f' '.' | sort -ur)"
    maxlinewidth=$(echo "$linewidths" | sed -n '1p')
    linewidths=$(echo "$linewidths" | sed '1d')

    local centercommands=""
    @@ -72,24 +86,37 @@ makemultilinedisklabel () {
    centercommands+="s/^(${linewidth})$/$left\1$right/; "
    done
    thelines=$(echo "$thelines" | sed -E "$centercommands s/\./0/g")
    printf "01%04x%04x$thelines" $((${#maxlinewidth} / 2)) $(echo "$thelines" | wc -l) | xxd -p -r > "$tempfolder/disk_label$suffix"
    printf "01%04x%04x$thelines" $((${#maxlinewidth} / 2)) "$(echo "$thelines" | wc -l)" | xxd -p -r > "$tempfolder/disk_label$suffix"

    [[ -f "$folder/.disk_label$suffix" ]] && sudo chflags noschg "$folder/.disk_label$suffix"
    sudo cp "$tempfolder/disk_label$suffix" "$folder/.disk_label$suffix"
    sudo chflags schg "$folder/.disk_label$suffix"
    [[ -f $folder/.disk_label.contentDetails ]] && sudo touch $folder/.disk_label.contentDetails
    #sudo bless --folder "$folder" --labelfile "$tempfolder/disk_label$suffix"
    #dump_label "$folder/.disk_label$suffix"
    done

    [[ -f "$folder/.disk_label.contentDetails" ]] && sudo chflags noschg "$folder/.disk_label.contentDetails"
    theoneline="${theoneline/🄳/ [D]}"
    theoneline="${theoneline/🄿/ [P]}"
    theoneline="${theoneline/🅁/ [R]}"
    theoneline="${theoneline/🄱/ [B]}"
    printf "$theoneline" > "$tempfolder/disk_label.contentDetails"
    sudo cp "$tempfolder/disk_label.contentDetails" "$folder/.disk_label.contentDetails"
    sudo chflags schg "$folder/.disk_label.contentDetails"
    }


    unsetall () {
    eval "$(set | sed -nE '/^('"$1"'[^=]*)=.*/s//unset \1/p')"
    local thevarprefix="$1" # prefix for variable names
    if [[ -n $thevarprefix ]]; then
    eval "$(set | sed -nE '/^('"$1"'[^=]*)=.*/s//unset \1/p')"
    fi
    }


    fixapfsbooter () {
    # Use Catalina for best results.

    theoneapfsmountpoint="$1"
    theline1="$2"

    @@ -103,6 +130,11 @@ fixapfsbooter () {
    return 1
    fi

    local diskutil_fab1_Error=""
    local diskutil_fab1_APFSContainerReference=""
    local diskutil_fab1_APFSVolumeGroupID=""
    local diskutil_fab1_MountPoint=""
    local diskutil_fab1_VolumeUUID=""
    getdiskinfo "$theoneapfsmountpoint" "diskutil_fab1_"
    if [[ -n $diskutil_fab1_Error ]]; then
    echo "# Error: $diskutil_fab1_Error"
    @@ -123,83 +155,127 @@ fixapfsbooter () {
    else
    echo "# Did not find icon at $iconsource"
    fi

    local Recovery_MountPoint=""

    for thedisk in $(getapfsroles $diskutil_fab1_APFSContainerReference); do
    #thedisk="5CF6AC3D-4597-439F-8501-E07149A248C5_System=disk12s5"
    #thedisk="_Recovery=disk12s3"
    if [[ $thedisk =~ "(${diskutil_fab1_APFSVolumeGroupID}_System|${diskutil_fab1_APFSVolumeGroupID}_Data|_Preboot|_Recovery)=" ]]; then
    echo "#================"
    echo "# Doing $thedisk"
    local patAll="^(_|${diskutil_fab1_APFSVolumeGroupID}_System|${diskutil_fab1_APFSVolumeGroupID}_Data|_Preboot|_Recovery)="
    local patSys="^_="
    local patSys2="^${diskutil_fab1_APFSVolumeGroupID}_System="
    local patData="^${diskutil_fab1_APFSVolumeGroupID}_Data="
    local patPreboot="^_Preboot="
    local patRecovery="^_Recovery="

    local System_UUID="$diskutil_fab1_APFSVolumeGroupID"
    if [[ -z $System_UUID ]]; then
    System_UUID="$diskutil_fab1_VolumeUUID"
    fi

    for thepass in 0 1; do
    for thedisk in $(getapfsroles "$diskutil_fab1_APFSContainerReference"); do
    if [[ $thedisk =~ $patAll ]]; then
    echo "#================"
    echo "# Doing $thedisk, pass $(( thepass+1 ))"

    local thedevice="${thedisk#*=}"
    diskutil mount "$thedevice" > /dev/null 2>&1
    getdiskinfo "$thedevice" "diskutil_fab2_"
    if [[ -z "$diskutil_fab2_MountPoint" ]]; then
    echo "# Could not mount"
    else
    if [[ "$diskutil_fab2_MountPoint" == "$diskutil_fab1_MountPoint" ]]; then
    echo "# Skipping icon copy"
    elif [[ -f "$iconsource" ]]; then
    echo "# Doing icon copy"
    sudo cp "$iconsource" "$diskutil_fab2_MountPoint" || echo "# Error copying icon"
    local thedevice="${thedisk#*=}"
    diskutil mount "$thedevice" > /dev/null 2>&1
    getdiskinfo "$thedevice" "diskutil_fab2_"
    if [[ -z "$diskutil_fab2_MountPoint" ]]; then
    echo "# Could not mount"
    else
    echo "# No icon to copy"
    fi

    local theletter=""
    local thedest=""

    if [[ $thedisk =~ "${diskutil_fab1_APFSVolumeGroupID}_System=" ]]; then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif [[ $thedisk =~ "${diskutil_fab1_APFSVolumeGroupID}_Data=" ]]; then
    theletter="🄳"
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif [[ $thedisk =~ "_Preboot=" ]]; then
    theletter="🄿"
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_APFSVolumeGroupID/System/Library/CoreServices"
    elif [[ $thedisk =~ "_Recovery=" ]]; then
    theletter="🅁"
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_APFSVolumeGroupID"
    fi

    if [[ -d $thedest ]]; then
    echo "# Destination at $thedest"
    local issource=0

    if [[ "$diskutil_fab2_MountPoint" == "$diskutil_fab1_MountPoint" ]]; then
    issource=1
    fi

    local theletter=""
    local thedest=""

    if [[ $thedisk =~ "_Recovery=" ]]; then
    if [[ -f "$thedest/boot.efi" ]]; then
    echo "# Blessing $thedest/boot.efi"
    sudo bless --folder "$thedest" --file "$thedest/boot.efi"
    if [[ $thedisk =~ $patSys ]]; then
    if ((issource)); then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    fi
    elif [[ $thedisk =~ $patSys2 ]]; then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif [[ $thedisk =~ $patData ]]; then
    theletter="🄳"
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif [[ $thedisk =~ $patPreboot ]]; then
    theletter="🄿"
    thedest="$diskutil_fab2_MountPoint/$System_UUID/System/Library/CoreServices"
    if [[ ! -d $thedest ]]; then
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_VolumeUUID/System/Library/CoreServices"
    fi
    elif [[ $thedisk =~ $patRecovery ]]; then
    theletter="🅁"
    thedest="$diskutil_fab2_MountPoint/$System_UUID"
    if [[ ! -d $thedest ]]; then
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_VolumeUUID"
    fi
    Recovery_MountPoint="$diskutil_fab2_MountPoint"
    fi

    local version=""
    local theversionfile="$thedest/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    if ((thepass == 0)); then
    if ((issource)); then
    echo "# Skipping icon copy"
    elif [[ -f "$iconsource" ]]; then
    echo "# Doing icon copy"
    sudo cp "$iconsource" "$diskutil_fab2_MountPoint" || echo "# Error copying icon"
    else
    echo "# No icon to copy"
    fi
    fi

    if [[ -d $thedest ]]; then
    echo "# Destination at $thedest"

    if ((thepass == 0)); then
    local version=""
    local theversionfile="$thedest/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi

    local theline2=""
    if [[ -n "$version" ]]; then
    theline2="${version} ${theletter}"
    local theline2=""
    if [[ -n "$version" ]]; then
    theline2="${version}${theletter}"
    else
    theline2="${theletter}"
    fi

    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${theline2}"

    echo "# Setting the label to: [${theline1}][${theline2}]"
    sudo find "$thedest" -name '.disk_label*' -exec chflags noschg {} \;
    sudo cp /tmp/disklabeltemp/.disk_label* "$thedest"
    sudo find "$thedest" -name '.disk_label*' -exec chflags schg {} \;
    else
    if [[ -f "$thedest/boot.efi" ]]; then
    echo "# Blessing $thedest/boot.efi"
    if [[ -f "$directbless" ]]; then
    sudo "$directbless" --folder "$thedest" --file "$thedest/boot.efi"
    else
    if [[ -z $theletter ]]; then
    # Blessing the system volume will bless Preboot, so temporarily change it to Recovery
    # but first must change Recovery to none. This only works in Catalina
    diskutil apfs changeVolumeRole "$Recovery_MountPoint" clear || echo "# ERROR: Unexpected error attempting to change role of Recovery volume"
    diskutil apfs changeVolumeRole "$diskutil_fab2_MountPoint" R || echo "# ERROR: Retry this from a different macOS Catalina system"
    fi
    sudo bless --folder "$thedest" --file "$thedest/boot.efi"
    if [[ -z $theletter ]]; then
    diskutil apfs changeVolumeRole "$diskutil_fab2_MountPoint" clear || echo "# ERROR: Retry this from a different macOS Catalina system"
    diskutil apfs changeVolumeRole "$Recovery_MountPoint" R || echo "# ERROR: Unexpected error attempting to change role of Recovery volume"
    fi
    fi
    fi
    fi
    else
    theline2="${theletter}"
    echo "# Destination does not exist $thedest"
    fi

    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${theline2}"

    echo "# Setting the label to: [${theline1}][${theline2}]"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags noschg {} \;
    sudo cp /tmp/disklabeltemp/.disk_label* "$thedest"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags schg {} \;
    [[ -f "$thedest/.disk_label.contentDetails" ]] && sudo rm "$thedest/.disk_label.contentDetails"
    #sudo echo -n "${theline1} (${theletter}) ${theline2}" > "$thedest/.disk_label.contentDetails"
    else
    echo "# Destination does not exist $thedest"
    fi

    fi
    fi
    done
    fi # if mount
    fi # if the disk
    done # for thedisk
    done # for thepass
    echo "#================"
    echo "# Done!"
    }
    @@ -208,7 +284,7 @@ fixapfsbooter () {
    getvolumeproperty () {
    local slice="$1"
    local property="$2"
    eval "$(diskutil info -plist /dev/$slice | plutil -p - | sed -nE '/^ *"'"$property"'" => (.*)/s//echo \1/p')"
    eval "$(diskutil info -plist "$slice" | plutil -p - | sed -nE '/^ *"'"$property"'" => (.*)/s//echo \1/p')"
    }


    @@ -222,7 +298,8 @@ mountEFIpartitions () {
    local diskinfo=""
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +EFI (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local volume=""
    volume="$(getvolumename "$slice")"
    mountpartition "_msdos" "$slice" "$volume" > /dev/null
    done
    }
    @@ -232,7 +309,8 @@ mountRecoveryHDpartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_Boot (\xe2\x81\xa8)?(Recovery HD)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local volume=""
    volume="$(getvolumename "$slice")"
    mountpartition "_hfs" "$slice" "$volume" > /dev/null
    done
    }
    @@ -242,7 +320,8 @@ mountRecoveryPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Recovery)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local volume=""
    volume="$(getvolumename "$slice")"
    mountpartition "_apfs" "$slice" "$volume" > /dev/null
    done
    }
    @@ -252,40 +331,50 @@ mountPrebootPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Preboot)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local volume=""
    volume="$(getvolumename "$slice")"
    mountpartition "_apfs" "$slice" "$volume" > /dev/null
    done
    }


    getblessinfo () {
    local mountpoint="$1"
    local thevarprefix="$2"
    unsetall "$thevarprefix"
    eval "$(bless -plist --info "$mountpoint" | plutil -convert json -o - - | perl -e '
    use JSON::PP; my $f = decode_json (<>)->{"Finder Info"};
    printf("'"$thevarprefix"'theblessfolder=\"%s\"\n'"$thevarprefix"'theblessfile=\"%s\"\n'"$thevarprefix"'theblessopen=\"%s\"\n", $f->[0]->{"Path"}, $f->[1]->{"Path"}, $f->[2]->{"Path"})')"
    }


    dumpAllDiskLabels () {
    IFS=$'\n'
    for theslice in $(diskutil list | sed -nE '/.*(disk[0-9]+s[0-9]+)$/s//\1/p'); do
    #echo $theslice
    diskutil mount $theslice > /dev/null 2>&1
    getdiskinfo $theslice "diskutil_dadl_"
    #echo "$theslice"
    sudo diskutil mount "$theslice" > /dev/null 2>&1
    local diskutil_dadl_DeviceIdentifier=""
    getdiskinfo "$theslice" "diskutil_dadl_"
    if [[ -n "$diskutil_dadl_MountPoint" ]]; then
    echo "#==========="
    echo $diskutil_dadl_DeviceIdentifier $diskutil_dadl_MountPoint

    local theblessinfo="$(bless --info "$diskutil_dadl_MountPoint")"
    echo "$diskutil_dadl_DeviceIdentifier $diskutil_dadl_MountPoint"
    local theblessfolder=""
    local theblessfile=""
    local theopen=""
    eval $(echo "$theblessinfo" | sed -nE '/^finderinfo\[0\]: +[0-9]+ => Blessed System Folder is (.*)/s//theblessfolder="\1"/p; /^finderinfo\[1\]: +[0-9]+ => Blessed System File is (.*)/s//theblessfile="\1"/p; /^finderinfo\[2\]: +[0-9]+ => 1st dir in open-folder list is (.*)/s//theopen="\1"/p; ')
    local theblessopen=""
    getblessinfo "$diskutil_dadl_MountPoint"
    if [[ -n $theblessfile ]]; then
    theblessfolder="$(dirname "$theblessfile")"
    fi

    for thefolder in $( { ls -d "$diskutil_dadl_MountPoint/"*"/boot.efi" | sed -E '/\/boot.efi$/s///'; ls -d "$diskutil_dadl_MountPoint/"*"/System/Library/CoreServices"; ls -d "$theblessfolder" "$diskutil_dadl_MountPoint/System/Library/CoreServices" "$diskutil_dadl_MountPoint/EFI/BOOT" } 2> /dev/null | sort -u ); do
    for thefolder in $( { find "$diskutil_dadl_MountPoint" -maxdepth 2 -name "boot.efi" 2> /dev/null | sed -E '/\/boot.efi$/s///'; ls -d "$diskutil_dadl_MountPoint/"*"/System/Library/CoreServices"; ls -d "$theblessfolder" "$diskutil_dadl_MountPoint/System/Library/CoreServices" "$diskutil_dadl_MountPoint/EFI/BOOT" ; } 2> /dev/null | sort -u ); do
    local version=""
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi

    echo "${thefolder} ($version)"
    [[ -f $thefolder/.disk_label.contentDetails ]] && echo "contentDetails: $(cat "$thefolder/.disk_label.contentDetails")" || echo " missing .disk_label.contentDetails"
    [[ -f $thefolder/.disk_label_2x ]] && dump_label "$thefolder/.disk_label_2x" || echo " missing .disk_label_2x"
    [[ -f $thefolder/.disk_label ]] && dump_label "$thefolder/.disk_label" || echo " missing .disk_label"
    done
    @@ -299,24 +388,25 @@ makeLabelCommands () {

    # Only includes Apple_HFS and Apple_Boot partitions.
    IFS=$'\n'
    local thefolder=""
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_[HFSBoot]* (\xe2\x81\xa8)?([^ ].*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local volume=""
    volume="$(getvolumename "$slice")"
    local version=""
    local mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
    local theblessinfo="$(bless --info "$mountpoint")"
    local thefolder=""
    local thefile=""
    local theopen=""
    eval $(echo "$theblessinfo" | sed -nE '/^finderinfo\[0\]: +[0-9]+ => Blessed System Folder is (.*)/s//thefolder="\1"/p; /^finderinfo\[1\]: +[0-9]+ => Blessed System File is (.*)/s//thefile="\1"/p; /^finderinfo\[2\]: +[0-9]+ => 1st dir in open-folder list is (.*)/s//theopen="\1"/p; ')
    if [[ -n $thefile ]]; then
    thefolder="$(dirname "$thefile")"
    local mountpoint=""
    mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
    local theblessfolder=""
    local theblessfile=""
    local theblessopen=""
    getblessinfo "$mountpoint"
    if [[ -n $theblessfile ]]; then
    thefolder="$(dirname "$theblessfile")"
    if [[ "$thefolder" != /Volumes/*/System/Library/CoreServices ]]; then
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi
    echo "#$slice=$thefolder, $volume ($version)"
    printf 'makemultilinedisklabel "%s" "%s"$%c\\n%c"%s"\n' "$thefolder" "${volume/Recovery HD/Recovery}" "'" "'" "$version"
    fi
    fi
    @@ -327,13 +417,13 @@ makeLabelCommands () {
    for thefolder in $(find /Volumes/*/System/Library/CoreServices /Volumes/*/EFI/BOOT -maxdepth 0); do
    local volume=""
    local version=""
    volume="${thefolder/\/Volumes\//}"
    volume="${volume/\/System\/Library\/CoreServices/}"
    volume="${thefolder/\/System\/Library\/CoreServices/}"
    volume="${volume/\/EFI\/BOOT/}"
    volume="$(getvolumename "$volume")"
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi
    echo "#$thefolder ($version)"
    printf 'makemultilinedisklabel "%s" "%s"$%c\\n%c"%s"\n' "$thefolder" "${volume/Recovery HD/Recovery}" "'" "'" "$version"
    done
    }
    @@ -345,17 +435,18 @@ clearOpenFolders () {
    IFS=$'\n'
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_HFS (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
    local volume=""
    volume="$(getvolumename "$slice")"
    local mountpoint=""
    mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
    echo "#$slice=$mountpoint,$volume ($version)"
    local theblessinfo="$(bless --info "$mountpoint")"
    local thefolder=""
    local thefile=""
    local theopen=""
    eval $(echo "$theblessinfo" | sed -nE '/^finderinfo\[0\]: +[0-9]+ => Blessed System Folder is (.*)/s//thefolder="\1"/p; /^finderinfo\[1\]: +[0-9]+ => Blessed System File is (.*)/s//thefile="\1"/p; /^finderinfo\[2\]: +[0-9]+ => 1st dir in open-folder list is (.*)/s//theopen="\1"/p; ')
    if [[ -n $theopen ]]; then
    local theblessfolder=""
    local theblessfile=""
    local theblessopen=""
    getblessinfo "$mountpoint"
    if [[ -n $theblessopen ]]; then
    echo "Clearing open folder list"
    sudo bless --folder "$thefolder" --file "$thefile"
    sudo bless --folder "$theblessfolder" --file "$theblessfile"
    fi
    done
    }
    @@ -366,27 +457,28 @@ getdiskinfo () {
    local thevarprefix="$2" # prefix for variable names
    # note: if thevarprefix is empty then you should clear any variables you want to use from this result beforehand
    unsetall "$thevarprefix"
    eval $(diskutil info -plist "$thedisk" | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'$thevarprefix'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }')
    eval "$(showdiskinfo "$thedisk" "$thevarprefix")"
    }


    showdiskinfo () {
    local thedisk="$1" # the disk you want info for (either a mountpoint like "/" or a device "disk0s1")
    local thevarprefix="$2" # prefix for variable names
    diskutil info -plist "$thedisk" | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'$thevarprefix'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }'
    diskutil info -plist "$thedisk" | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'"$thevarprefix"'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }'
    }


    getapfsroles () {
    # $1 = the apfs container
    local patVolumeGroup="^(Data|System)="
    for theapfsvolume in $(
    diskutil apfs list -plist "$1" | plutil -convert json -o - - | perl -e '
    use JSON::PP; my $apfs = decode_json (<>);
    foreach my $volume (@{$apfs->{Containers}[0]{Volumes}}) {print $volume->{Roles}[0] . "=" . $volume->{DeviceIdentifier} . "\n";}
    '
    ); do
    diskutil_role_APFSVolumeGroupID=""
    if [[ $theapfsvolume =~ "Data|System=" ]]; then
    if [[ $theapfsvolume =~ $patVolumeGroup ]]; then
    getdiskinfo "${theapfsvolume#*=}" "diskutil_role_"
    fi
    echo "${diskutil_role_APFSVolumeGroupID}_${theapfsvolume}"
    @@ -398,10 +490,13 @@ setbootername () {
    local thedisk="$1"
    local NewBooterName="$2"

    local diskutil_sbn_Root_BooterDeviceIdentifier=""
    getdiskinfo "$thedisk" diskutil_sbn_Root_
    if [[ -n $diskutil_sbn_Root_BooterDeviceIdentifier ]]; then
    diskutil mount $diskutil_sbn_Root_BooterDeviceIdentifier
    getdiskinfo $diskutil_sbn_Root_BooterDeviceIdentifier diskutil_sbn_Preboot_
    diskutil mount "$diskutil_sbn_Root_BooterDeviceIdentifier"
    local diskutil_sbn_Root_VolumeUUID=""
    local diskutil_sbn_Root_APFSVolumeGroupID=""
    getdiskinfo "$diskutil_sbn_Root_BooterDeviceIdentifier" "diskutil_sbn_Preboot_"
    if [[ -n $diskutil_sbn_Preboot_MountPoint ]]; then
    local theUUID=""
    if [[ -d $diskutil_sbn_Preboot_MountPoint/$diskutil_sbn_Root_VolumeUUID ]]; then
    @@ -415,7 +510,7 @@ setbootername () {
    ls -l "$diskutil_sbn_Preboot_MountPoint"
    return 1
    fi
    thefile="$diskutil_sbn_Preboot_MountPoint/$theUUID/System/Library/CoreServices/.disk_label.contentDetails"
    local thefile="$diskutil_sbn_Preboot_MountPoint/$theUUID/System/Library/CoreServices/.disk_label.contentDetails"
    if [[ -f "$thefile" ]]; then
    echo "$thefile already exists: $(cat "$thefile")"
    else
    @@ -429,3 +524,64 @@ setbootername () {
    echo "No booter device"
    fi
    }


    doperlonmounteddisks () {
    diskutil list -plist | plutil -convert json -o - - | perl -e '
    use JSON::PP; my $disks = decode_json (<>)->{AllDisksAndPartitions};
    foreach my $disk (@$disks) {
    foreach my $type ("APFSVolumes","Partitions") {
    foreach my $part (@{$disk->{$type}}) {
    if (exists $part->{MountPoint}) {
    '"$1"'
    }
    }
    }
    }
    '
    }


    getallmounteddisks () {
    # not all disks are mounted at /Volumes so use diskutil to find them
    if [[ "$1" == "-d" ]]; then
    doperlonmounteddisks 'print $part->{DeviceIdentifier} . ":" . $part->{MountPoint} . "\n";'
    else
    doperlonmounteddisks 'print $part->{MountPoint} . "\n";'
    fi
    }


    fixcustomiconflag () {
    local thefolder="$1"
    # if the folder is a mount point then the icon should be in datafork of ".VolumeIcon.icns"
    # otherwise the icon should be in a icns resource in "Icon\n"
    local thefinderinfo=""
    local newfinderinfo=""
    thefinderinfo=$(xattr -px com.apple.FinderInfo "$thefolder" 2> /dev/null | xxd -p -r | xxd -p -c 32)
    if [[ -z "$thefinderinfo" ]]; then
    newfinderinfo="0000000000000000040000000000000000000000000000000000000000000000"
    echo "# creating FinderInfo $newfinderinfo $thefolder"
    else
    newfinderinfo=${thefinderinfo:0:17}$(printf "%x" $((${thefinderinfo:17:1} | 4)) )${thefinderinfo:18}
    if [[ "$newfinderinfo" != "$thefinderinfo" ]]; then
    echo "# modifying FinderInfo $newfinderinfo $thefolder"
    else
    echo "# unchanged FinderInfo $newfinderinfo $thefolder"
    fi
    fi

    if [[ "$newfinderinfo" != "$thefinderinfo" ]]; then
    xattr -wx com.apple.FinderInfo "$newfinderinfo" "$thefolder"
    fi
    }


    fixcustomiconflagofallvolumes () {
    IFS=$'\n'
    for themount in $(getallmounteddisks); do
    if [[ -f "$themount/.VolumeIcon.icns" ]]; then
    fixcustomiconflag "$themount"
    fi
    done
    }
  13. joevt revised this gist Dec 31, 2020. 1 changed file with 141 additions and 102 deletions.
    243 changes: 141 additions & 102 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # by joevt Dec 25, 2020
    # by joevt Dec 30, 2020

    # dump disk_label file
    dump_label () { local contents=$(xxd -p -c99999 "$1"); echo ${contents:10} | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }
    @@ -84,69 +84,88 @@ makemultilinedisklabel () {
    }


    unsetall () {
    eval "$(set | sed -nE '/^('"$1"'[^=]*)=.*/s//unset \1/p')"
    }


    fixapfsbooter () {
    # The first parameter is the mount point for the system volume, the second parameter is the base name I want to use for my Disk Label.

    local theosmountpoint="$1"
    local theline1="$2"

    if [[ -d "$theosmountpoint/System/Library/CoreServices" ]]; then
    mkdir -p /tmp/disklabeltemp

    local DiskUUID=""
    local APFSContainerReference=""
    local BooterDeviceIdentifier=""
    local RecoveryDeviceIdentifier=""
    local DeviceIdentifier=""
    getdiskinfo "$theosmountpoint"
    local theDiskUUID=$DiskUUID
    local theRootDeviceIdentifier="$DeviceIdentifier"
    local theBooterDeviceIdentifier="$BooterDeviceIdentifier"
    local theRecoveryDeviceIdentifier="$RecoveryDeviceIdentifier"
    local theDataDeviceIdentifier=""
    local theAPFSContainerReference="$APFSContainerReference"

    # Find the Data volume (Catalina or later)
    if [[ -n $theAPFSContainerReference ]]; then
    local theDataDeviceIdentifier=$(diskutil apfs list $theAPFSContainerReference | perl -nE '/^[| ]*APFS Volume Disk \(Role\): *(disk\d+s\d+) *\(Data\)/ && print $1')
    theoneapfsmountpoint="$1"
    theline1="$2"

    if [[ -z $theoneapfsmountpoint ]]; then
    echo "#Error: missing parameters"
    return 1
    fi

    if [[ -z $theline1 ]]; then
    echo "#Error: missing second parameter"
    return 1
    fi

    getdiskinfo "$theoneapfsmountpoint" "diskutil_fab1_"
    if [[ -n $diskutil_fab1_Error ]]; then
    echo "# Error: $diskutil_fab1_Error"
    return 1
    fi

    mkdir -p /tmp/disklabeltemp

    local iconsource="$theoneapfsmountpoint/.VolumeIcon.icns"
    if [[ -f "$iconsource" ]]; then
    echo "# Got icon at $iconsource"
    if [[ -L "$iconsource" ]]; then
    echo "# Making icon not a sym link"
    cp -p "$iconsource" /tmp/disklabeltemp
    sudo rm "$iconsource"
    sudo cp -p /tmp/disklabeltemp/.VolumeIcon.icns "$iconsource"
    fi
    else
    echo "# Did not find icon at $iconsource"
    fi

    for thedisk in $(getapfsroles $diskutil_fab1_APFSContainerReference); do
    #thedisk="5CF6AC3D-4597-439F-8501-E07149A248C5_System=disk12s5"
    #thedisk="_Recovery=disk12s3"
    if [[ $thedisk =~ "(${diskutil_fab1_APFSVolumeGroupID}_System|${diskutil_fab1_APFSVolumeGroupID}_Data|_Preboot|_Recovery)=" ]]; then
    echo "#================"
    echo "# Doing $thedisk"

    # For the volume icon, replace the symlink (used in the System volume of Catalina or Big Sur if you can get write access) with a copy of the
    # actual icon from the data volume. This will make the icon visible in the Finder when you boot from a different system such as High Sierra.
    if [[ -L "$theosmountpoint/.VolumeIcon.icns" ]]; then
    echo "Icon is sym link"
    cp -p "$theosmountpoint/.VolumeIcon.icns" /tmp/disklabeltemp
    sudo rm "$theosmountpoint/.VolumeIcon.icns"
    sudo cp -p /tmp/disklabeltemp/.VolumeIcon.icns "$theosmountpoint"
    fi
    local thedevice="${thedisk#*=}"
    diskutil mount "$thedevice" > /dev/null 2>&1
    getdiskinfo "$thedevice" "diskutil_fab2_"
    if [[ -z "$diskutil_fab2_MountPoint" ]]; then
    echo "# Could not mount"
    else
    if [[ "$diskutil_fab2_MountPoint" == "$diskutil_fab1_MountPoint" ]]; then
    echo "# Skipping icon copy"
    elif [[ -f "$iconsource" ]]; then
    echo "# Doing icon copy"
    sudo cp "$iconsource" "$diskutil_fab2_MountPoint" || echo "# Error copying icon"
    else
    echo "# No icon to copy"
    fi

    # Bless the System, Preboot, Recovery, and Data volumes. The first 3 will appear in the Startup Manager (hold option at boot).
    # All of them will get the same volume icon.
    # Create a two line disk label that includes the system version (plus the letter P, R, or D for the Preboot, Recovery, Data volumes)
    # Lock the disk label so that macOS doesn't overwrite it
    for theitem in ":$theRootDeviceIdentifier" "🄿:$theBooterDeviceIdentifier" "🅁:$theRecoveryDeviceIdentifier" "🄳:$theDataDeviceIdentifier"; do
    local theletter="${theitem%:*}"
    local thedevice="${theitem#*:}"

    if [[ -n $thedevice ]]; then
    diskutil mount "$thedevice" > /dev/null
    local MountPoint=""
    getdiskinfo "$thedevice"
    if [[ -n $MountPoint ]]; then
    if [[ $theletter != '' ]]; then
    [[ -f "$theosmountpoint/.VolumeIcon.icns" ]] && sudo cp "$theosmountpoint/.VolumeIcon.icns" "$MountPoint" || echo "No volume icon to copy to $theitem"
    fi
    local theletter=""
    local thedest=""

    if [[ $thedisk =~ "${diskutil_fab1_APFSVolumeGroupID}_System=" ]]; then
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif [[ $thedisk =~ "${diskutil_fab1_APFSVolumeGroupID}_Data=" ]]; then
    theletter="🄳"
    thedest="$diskutil_fab2_MountPoint/System/Library/CoreServices"
    elif [[ $thedisk =~ "_Preboot=" ]]; then
    theletter="🄿"
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_APFSVolumeGroupID/System/Library/CoreServices"
    elif [[ $thedisk =~ "_Recovery=" ]]; then
    theletter="🅁"
    thedest="$diskutil_fab2_MountPoint/$diskutil_fab1_APFSVolumeGroupID"
    fi

    if [[ -d $thedest ]]; then
    echo "# Destination at $thedest"

    local thedest=""

    if [[ $theletter == '' ]] && [[ -d "$MountPoint/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/System/Library/CoreServices"
    elif [[ $theletter == '🄳' ]] && [[ -d "$MountPoint/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/System/Library/CoreServices"
    elif [[ $theletter == '🄿' ]] && [[ -d "$MountPoint/$theDiskUUID/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/$theDiskUUID/System/Library/CoreServices"
    elif [[ $theletter == '🅁' ]] && [[ -f "$MountPoint/$theDiskUUID/boot.efi" ]]; then
    thedest="${MountPoint}/${theDiskUUID}"
    if [[ $thedisk =~ "_Recovery=" ]]; then
    if [[ -f "$thedest/boot.efi" ]]; then
    echo "# Blessing $thedest/boot.efi"
    sudo bless --folder "$thedest" --file "$thedest/boot.efi"
    @@ -158,27 +177,31 @@ fixapfsbooter () {
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi

    if [[ -n "$thedest" ]]; then
    if [[ -n "$version" ]]; then
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${version} ${theletter}"
    else
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${theletter}"
    fi

    echo "# ${theline1} ${theline2}: Destination for ${theletter} $thedevice $thedest"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags noschg {} \;
    sudo cp /tmp/disklabeltemp/.disk_label* "$thedest"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags schg {} \;
    [[ -f "$thedest/.disk_label.contentDetails" ]] && sudo rm "$thedest/.disk_label.contentDetails"
    #sudo echo -n "${theline1} (${theletter}) ${theline2}" > "$thedest/.disk_label.contentDetails"

    local theline2=""
    if [[ -n "$version" ]]; then
    theline2="${version} ${theletter}"
    else
    echo "# ${theline1} ${theline2}: No destination for ${theletter} $thedevice $MountPoint"
    theline2="${theletter}"
    fi

    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${theline2}"

    echo "# Setting the label to: [${theline1}][${theline2}]"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags noschg {} \;
    sudo cp /tmp/disklabeltemp/.disk_label* "$thedest"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags schg {} \;
    [[ -f "$thedest/.disk_label.contentDetails" ]] && sudo rm "$thedest/.disk_label.contentDetails"
    #sudo echo -n "${theline1} (${theletter}) ${theline2}" > "$thedest/.disk_label.contentDetails"
    else
    echo "# Destination does not exist $thedest"
    fi

    fi
    done
    fi
    fi
    done
    echo "#================"
    echo "# Done!"
    }


    @@ -240,13 +263,12 @@ dumpAllDiskLabels () {
    for theslice in $(diskutil list | sed -nE '/.*(disk[0-9]+s[0-9]+)$/s//\1/p'); do
    #echo $theslice
    diskutil mount $theslice > /dev/null 2>&1
    local MountPoint=""
    getdiskinfo $theslice
    if [[ -n "$MountPoint" ]]; then
    getdiskinfo $theslice "diskutil_dadl_"
    if [[ -n "$diskutil_dadl_MountPoint" ]]; then
    echo "#==========="
    echo $DeviceIdentifier $MountPoint
    echo $diskutil_dadl_DeviceIdentifier $diskutil_dadl_MountPoint

    local theblessinfo="$(bless --info "$MountPoint")"
    local theblessinfo="$(bless --info "$diskutil_dadl_MountPoint")"
    local theblessfolder=""
    local theblessfile=""
    local theopen=""
    @@ -255,7 +277,7 @@ dumpAllDiskLabels () {
    theblessfolder="$(dirname "$theblessfile")"
    fi

    for thefolder in $( { ls -d "$MountPoint/"*"/boot.efi" | sed -E '/\/boot.efi$/s///'; ls -d "$MountPoint/"*"/System/Library/CoreServices"; ls -d "$theblessfolder" "$MountPoint/System/Library/CoreServices" "$MountPoint/EFI/BOOT" } 2> /dev/null | sort -u ); do
    for thefolder in $( { ls -d "$diskutil_dadl_MountPoint/"*"/boot.efi" | sed -E '/\/boot.efi$/s///'; ls -d "$diskutil_dadl_MountPoint/"*"/System/Library/CoreServices"; ls -d "$theblessfolder" "$diskutil_dadl_MountPoint/System/Library/CoreServices" "$diskutil_dadl_MountPoint/EFI/BOOT" } 2> /dev/null | sort -u ); do
    local version=""
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    @@ -340,51 +362,68 @@ clearOpenFolders () {
    getdiskinfo () {
    # $1 = the disk you want info for (either a mountpoint like "/" or a device "disk0s1")
    # $2 = prefix for variable names
    # note: you should clear any variables you want to use from this result beforehand
    eval $(diskutil info -plist $1 | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'$2'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }')
    local thedisk="$1" # the disk you want info for (either a mountpoint like "/" or a device "disk0s1")
    local thevarprefix="$2" # prefix for variable names
    # note: if thevarprefix is empty then you should clear any variables you want to use from this result beforehand
    unsetall "$thevarprefix"
    eval $(diskutil info -plist "$thedisk" | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'$thevarprefix'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }')
    }
    showdiskinfo () {
    # $1 = the disk you want info for (either a mountpoint like "/" or a device "disk0s1")
    # $2 = prefix for variable names
    # note: you should clear any variables you want to use from this result beforehand
    diskutil info -plist $1 | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'$2'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }'
    local thedisk="$1" # the disk you want info for (either a mountpoint like "/" or a device "disk0s1")
    local thevarprefix="$2" # prefix for variable names
    diskutil info -plist "$thedisk" | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'$thevarprefix'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }'
    }
    getapfsroles () {
    # $1 = the apfs container
    for theapfsvolume in $(
    diskutil apfs list -plist "$1" | plutil -convert json -o - - | perl -e '
    use JSON::PP; my $apfs = decode_json (<>);
    foreach my $volume (@{$apfs->{Containers}[0]{Volumes}}) {print $volume->{Roles}[0] . "=" . $volume->{DeviceIdentifier} . "\n";}
    '
    ); do
    diskutil_role_APFSVolumeGroupID=""
    if [[ $theapfsvolume =~ "Data|System=" ]]; then
    getdiskinfo "${theapfsvolume#*=}" "diskutil_role_"
    fi
    echo "${diskutil_role_APFSVolumeGroupID}_${theapfsvolume}"
    done
    }
    setbootername () {
    local thedisk="$1"
    local NewBooterName="$2"
    getdiskinfo "$thedisk" Root
    if [[ -n $RootBooterDeviceIdentifier ]]; then
    diskutil mount $RootBooterDeviceIdentifier
    getdiskinfo $RootBooterDeviceIdentifier Preboot
    if [[ -n $PrebootMountPoint ]]; then
    getdiskinfo "$thedisk" diskutil_sbn_Root_
    if [[ -n $diskutil_sbn_Root_BooterDeviceIdentifier ]]; then
    diskutil mount $diskutil_sbn_Root_BooterDeviceIdentifier
    getdiskinfo $diskutil_sbn_Root_BooterDeviceIdentifier diskutil_sbn_Preboot_
    if [[ -n $diskutil_sbn_Preboot_MountPoint ]]; then
    local theUUID=""
    if [[ -d $PrebootMountPoint/$RootVolumeUUID ]]; then
    theUUID=$RootVolumeUUID
    if [[ -d $diskutil_sbn_Preboot_MountPoint/$diskutil_sbn_Root_VolumeUUID ]]; then
    theUUID=$diskutil_sbn_Root_VolumeUUID
    echo "using VolumeUUID"
    elif [[ -d $PrebootMountPoint/$RootAPFSVolumeGroupID ]]; then
    theUUID=$RootAPFSVolumeGroupID
    elif [[ -d $diskutil_sbn_Preboot_MountPoint/$diskutil_sbn_Root_APFSVolumeGroupID ]]; then
    theUUID=$diskutil_sbn_Root_APFSVolumeGroupID
    echo "using APFSVolumeGroupID"
    else
    echo "unknown UUID in booter"
    ls -l "$PrebootMountPoint"
    ls -l "$diskutil_sbn_Preboot_MountPoint"
    return 1
    fi
    thefile="$PrebootMountPoint/$theUUID/System/Library/CoreServices/.disk_label.contentDetails"
    thefile="$diskutil_sbn_Preboot_MountPoint/$theUUID/System/Library/CoreServices/.disk_label.contentDetails"
    if [[ -f "$thefile" ]]; then
    echo "$thefile already exists: $(cat "$thefile")"
    else
    sudo bash -c "echo \"$NewBooterName\" > \"$thefile\""
    echo "$thefile is created"
    fi
    else
    echo "$RootBooterDeviceIdentifier is not mounted"
    echo "$diskutil_sbn_Root_BooterDeviceIdentifier is not mounted"
    fi
    else
    echo "No booter device"
  14. joevt revised this gist Dec 26, 2020. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # by joevt Dec 21, 2020
    # by joevt Dec 25, 2020

    # dump disk_label file
    dump_label () { local contents=$(xxd -p -c99999 "$1"); echo ${contents:10} | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }
    @@ -197,7 +197,7 @@ getvolumename () {
    mountEFIpartitions () {
    IFS=$'\n'
    local diskinfo=""
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +EFI (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +EFI (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_msdos" "$slice" "$volume" > /dev/null
    @@ -207,7 +207,7 @@ mountEFIpartitions () {

    mountRecoveryHDpartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +Apple_Boot (\xe2\x81\xa8)?(Recovery HD)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_Boot (\xe2\x81\xa8)?(Recovery HD)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_hfs" "$slice" "$volume" > /dev/null
    @@ -217,7 +217,7 @@ mountRecoveryHDpartitions() {

    mountRecoveryPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Recovery)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Recovery)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_apfs" "$slice" "$volume" > /dev/null
    @@ -227,7 +227,7 @@ mountRecoveryPartitions() {

    mountPrebootPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Preboot)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Preboot)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_apfs" "$slice" "$volume" > /dev/null
    @@ -277,7 +277,7 @@ makeLabelCommands () {
    # Only includes Apple_HFS and Apple_Boot partitions.
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +Apple_[HFSBoot]* (\xe2\x81\xa8)?([^ ].*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_[HFSBoot]* (\xe2\x81\xa8)?([^ ].*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local version=""
    @@ -321,7 +321,7 @@ clearOpenFolders () {
    # Clear open folder list of hfs partitions (finderinfo[2] in bless --info).
    # If you have an HFS+ disk that has folders that open when you mount them (such as an installer), then this will stop that from happening.
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +Apple_HFS (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    for diskinfo in $(diskutil list | LANG=C sed -nE $'/^ *[0-9]+: +Apple_HFS (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
  15. joevt revised this gist Dec 22, 2020. 1 changed file with 16 additions and 7 deletions.
    23 changes: 16 additions & 7 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # by joevt Dec 19, 2020
    # by joevt Dec 21, 2020

    # dump disk_label file
    dump_label () { local contents=$(xxd -p -c99999 "$1"); echo ${contents:10} | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }
    @@ -85,6 +85,8 @@ makemultilinedisklabel () {


    fixapfsbooter () {
    # The first parameter is the mount point for the system volume, the second parameter is the base name I want to use for my Disk Label.

    local theosmountpoint="$1"
    local theline1="$2"

    @@ -104,17 +106,24 @@ fixapfsbooter () {
    local theDataDeviceIdentifier=""
    local theAPFSContainerReference="$APFSContainerReference"

    # Find the Data volume (Catalina or later)
    if [[ -n $theAPFSContainerReference ]]; then
    local theDataDeviceIdentifier=$(diskutil apfs list $theAPFSContainerReference | perl -nE '/^[| ]*APFS Volume Disk \(Role\): *(disk\d+s\d+) *\(Data\)/ && print $1')
    fi

    # For the volume icon, replace the symlink (used in the System volume of Catalina or Big Sur if you can get write access) with a copy of the
    # actual icon from the data volume. This will make the icon visible in the Finder when you boot from a different system such as High Sierra.
    if [[ -L "$theosmountpoint/.VolumeIcon.icns" ]]; then
    echo "Icon is sym link"
    cp -p "$theosmountpoint/.VolumeIcon.icns" /tmp/disklabeltemp
    sudo rm "$theosmountpoint/.VolumeIcon.icns"
    sudo cp -p /tmp/disklabeltemp/.VolumeIcon.icns "$theosmountpoint"
    fi

    # Bless the System, Preboot, Recovery, and Data volumes. The first 3 will appear in the Startup Manager (hold option at boot).
    # All of them will get the same volume icon.
    # Create a two line disk label that includes the system version (plus the letter P, R, or D for the Preboot, Recovery, Data volumes)
    # Lock the disk label so that macOS doesn't overwrite it
    for theitem in ":$theRootDeviceIdentifier" "🄿:$theBooterDeviceIdentifier" "🅁:$theRecoveryDeviceIdentifier" "🄳:$theDataDeviceIdentifier"; do
    local theletter="${theitem%:*}"
    local thedevice="${theitem#*:}"
    @@ -188,7 +197,7 @@ getvolumename () {
    mountEFIpartitions () {
    IFS=$'\n'
    local diskinfo=""
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +EFI (.*[^ ]) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +EFI (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_msdos" "$slice" "$volume" > /dev/null
    @@ -198,7 +207,7 @@ mountEFIpartitions () {

    mountRecoveryHDpartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +Apple_Boot (Recovery HD) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +Apple_Boot (\xe2\x81\xa8)?(Recovery HD)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_hfs" "$slice" "$volume" > /dev/null
    @@ -208,7 +217,7 @@ mountRecoveryHDpartitions() {

    mountRecoveryPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +APFS Volume (Recovery) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Recovery)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_apfs" "$slice" "$volume" > /dev/null
    @@ -218,7 +227,7 @@ mountRecoveryPartitions() {

    mountPrebootPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +APFS Volume (Preboot) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +APFS Volume (\xe2\x81\xa8)?(Preboot)(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_apfs" "$slice" "$volume" > /dev/null
    @@ -268,7 +277,7 @@ makeLabelCommands () {
    # Only includes Apple_HFS and Apple_Boot partitions.
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +Apple_[HFSBoot]* ([^ ].*[^ ]) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +Apple_[HFSBoot]* (\xe2\x81\xa8)?([^ ].*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local version=""
    @@ -312,7 +321,7 @@ clearOpenFolders () {
    # Clear open folder list of hfs partitions (finderinfo[2] in bless --info).
    # If you have an HFS+ disk that has folders that open when you mount them (such as an installer), then this will stop that from happening.
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +Apple_HFS (.*[^ ]) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    for diskinfo in $(diskutil list | sed -nE $'/^ *[0-9]+: +Apple_HFS (\xe2\x81\xa8)?(.*[^ \xa9])(\xe2\x81\xa9)? +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/''s//\2_\4/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
  16. joevt revised this gist Dec 19, 2020. 1 changed file with 36 additions and 27 deletions.
    63 changes: 36 additions & 27 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # by joevt Oct 6, 2020
    # by joevt Dec 19, 2020

    # dump disk_label file
    dump_label () { local contents=$(xxd -p -c99999 "$1"); echo ${contents:10} | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }
    @@ -9,21 +9,25 @@ mountpartition() {
    local mounttype=$1
    local slice=$2
    local volume=$3
    local mountpoint=$(mount | sed -n -E "/\/dev\/$slice on (.*) \(.*/s//\1/p")
    if [ -z $mountpoint ]; then
    i=0
    local startmountpoint="/Volumes/$volume"
    mountpoint="$startmountpoint"
    while [ -d "$mountpoint" ]; do
    ((i++))
    mountpoint="$startmountpoint$i"
    done
    fi
    if [ ! -d "$mountpoint" ]; then
    sudo mkdir "$mountpoint" 2> /dev/null
    sudo mount$mounttype "/dev/$slice" "$mountpoint"
    local mountpoint=""
    mountpoint=$(mount | sed -n -E "/\/dev\/$slice on (.*) \(.*/s//\1/p")
    if [[ -n "$mountpoint" ]]; then
    echo -n "$mountpoint"
    return 0
    fi
    echo -n "$mountpoint"
    local i=0
    local startmountpoint="/Volumes/$volume"
    mountpoint="$startmountpoint"
    while ((1)); do
    sudo mkdir "$mountpoint" 2> /dev/null && break
    if ((i++ > 1000)); then
    echo "Could not create mountpoint" 1>&2
    return 1
    fi
    mountpoint="$startmountpoint$i"
    done
    sudo "mount$mounttype" "/dev/$slice" "$mountpoint" && echo -n "$mountpoint"
    return $?
    }


    @@ -32,22 +36,21 @@ makemultilinedisklabel () {
    local lines="$2"
    local alllines=""
    local alllines2x=""

    [[ -d "/tmp/$folder" ]] || mkdir -p "/tmp/$folder"
    local tempfolder="$(mktemp -d)"

    IFS=$'\n'
    local linenum=0
    local theline=""
    for theline in $(echo "$lines"); do
    #echo "doing line: \"$theline\""
    #echo sudo bless --folder "$folder" --label "$theline"
    sudo bless --folder "/tmp/$folder" --label "$theline" 2> /dev/null
    sudo bless --folder "$tempfolder" --label "$theline" 2> /dev/null
    if (( $linenum )); then
    alllines+="$(dump_label "/tmp/$folder/.disk_label" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    alllines2x+="$(dump_label "/tmp/$folder/.disk_label_2x" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    alllines+="$(dump_label "$tempfolder/.disk_label" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    alllines2x+="$(dump_label "$tempfolder/.disk_label_2x" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    else
    alllines+="$(dump_label "/tmp/$folder/.disk_label")"$'\n'
    alllines2x+="$(dump_label "/tmp/$folder/.disk_label_2x")"$'\n'
    alllines+="$(dump_label "$tempfolder/.disk_label")"$'\n'
    alllines2x+="$(dump_label "$tempfolder/.disk_label_2x")"$'\n'
    fi
    ((linenum++))
    done
    @@ -69,13 +72,13 @@ makemultilinedisklabel () {
    centercommands+="s/^(${linewidth})$/$left\1$right/; "
    done
    thelines=$(echo "$thelines" | sed -E "$centercommands s/\./0/g")
    printf "01%04x%04x$thelines" $((${#maxlinewidth} / 2)) $(echo "$thelines" | wc -l) | xxd -p -r > "/tmp/$folder/disk_label$suffix"
    printf "01%04x%04x$thelines" $((${#maxlinewidth} / 2)) $(echo "$thelines" | wc -l) | xxd -p -r > "$tempfolder/disk_label$suffix"

    [[ -f "$folder/.disk_label$suffix" ]] && sudo chflags noschg "$folder/.disk_label$suffix"
    sudo cp "/tmp/$folder/disk_label$suffix" "$folder/.disk_label$suffix"
    sudo cp "$tempfolder/disk_label$suffix" "$folder/.disk_label$suffix"
    sudo chflags schg "$folder/.disk_label$suffix"
    [[ -f $folder/.disk_label.contentDetails ]] && sudo touch $folder/.disk_label.contentDetails
    #sudo bless --folder "$folder" --labelfile "/tmp/$folder/disk_label$suffix"
    #sudo bless --folder "$folder" --labelfile "$tempfolder/disk_label$suffix"
    #dump_label "$folder/.disk_label$suffix"
    done
    }
    @@ -170,9 +173,15 @@ fixapfsbooter () {
    }


    getvolumename () {
    getvolumeproperty () {
    local slice="$1"
    eval "$(diskutil info -plist /dev/$slice | plutil -p - | sed -nE '/^ *"VolumeName" => (.*)/s//echo \1/p')"
    local property="$2"
    eval "$(diskutil info -plist /dev/$slice | plutil -p - | sed -nE '/^ *"'"$property"'" => (.*)/s//echo \1/p')"
    }


    getvolumename () {
    getvolumeproperty "$1" "VolumeName"
    }


  17. joevt revised this gist Oct 7, 2020. 1 changed file with 63 additions and 62 deletions.
    125 changes: 63 additions & 62 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # by joevt Sep 30, 2020
    # by joevt Oct 6, 2020

    # dump disk_label file
    dump_label () { local contents=$(xxd -p -c99999 "$1"); echo ${contents:10} | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }
    @@ -84,24 +84,18 @@ makemultilinedisklabel () {
    fixapfsbooter () {
    local theosmountpoint="$1"
    local theline1="$2"
    local theline2="$3"

    if [[ -d "$theosmountpoint/System/Library/CoreServices" ]]; then
    mkdir -p /tmp/disklabeltemp
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${theline2}"
    #open /tmp/disklabeltemp
    #dump_label /private/tmp/disklabeltemp/.disk_label_2x
    sudo cp /tmp/disklabeltemp/.disk_label* "$theosmountpoint/System/Library/CoreServices"
    [[ -f "$theosmountpoint/System/Library/CoreServices/.disk_label.contentDetails" ]] && sudo rm "$theosmountpoint/System/Library/CoreServices/.disk_label.contentDetails"
    #sudo echo -n "${theline1} ${theline2}" > "$theosmountpoint/System/Library/CoreServices/.disk_label.contentDetails"
    #open "$theosmountpoint/System/Library/CoreServices"

    local DiskUUID=""
    local APFSContainerReference=""
    local BooterDeviceIdentifier=""
    local RecoveryDeviceIdentifier=""
    getdiskinfo $theosmountpoint
    local DeviceIdentifier=""
    getdiskinfo "$theosmountpoint"
    local theDiskUUID=$DiskUUID
    local theRootDeviceIdentifier="$DeviceIdentifier"
    local theBooterDeviceIdentifier="$BooterDeviceIdentifier"
    local theRecoveryDeviceIdentifier="$RecoveryDeviceIdentifier"
    local theDataDeviceIdentifier=""
    @@ -118,39 +112,48 @@ fixapfsbooter () {
    sudo cp -p /tmp/disklabeltemp/.VolumeIcon.icns "$theosmountpoint"
    fi

    for theitem in "P:$theBooterDeviceIdentifier" "R:$theRecoveryDeviceIdentifier" "D:$theDataDeviceIdentifier"; do
    local theletter="${theitem:0:1}"
    local thedevice="${theitem:2}"
    #echo $theletter
    #echo $thedevice
    for theitem in ":$theRootDeviceIdentifier" "🄿:$theBooterDeviceIdentifier" "🅁:$theRecoveryDeviceIdentifier" "🄳:$theDataDeviceIdentifier"; do
    local theletter="${theitem%:*}"
    local thedevice="${theitem#*:}"

    if [[ -n $thedevice ]]; then
    diskutil mount $thedevice > /dev/null
    diskutil mount "$thedevice" > /dev/null
    local MountPoint=""
    getdiskinfo $thedevice
    #echo $MountPoint
    getdiskinfo "$thedevice"
    if [[ -n $MountPoint ]]; then
    #open "$MountPoint"
    [[ -f "$theosmountpoint/.VolumeIcon.icns" ]] && sudo cp "$theosmountpoint/.VolumeIcon.icns" "$MountPoint" || echo "No volume icon to copy to $theitem"
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1} (${theletter})"$'\n'"${theline2}"
    #open "/tmp/disklabeltemp"
    #dump_label /tmp/disklabeltemp/.disk_label_

    if [[ $theletter != '' ]]; then
    [[ -f "$theosmountpoint/.VolumeIcon.icns" ]] && sudo cp "$theosmountpoint/.VolumeIcon.icns" "$MountPoint" || echo "No volume icon to copy to $theitem"
    fi

    local thedest=""

    if [[ $theletter == 'P' ]] && [[ -d "$MountPoint/$theDiskUUID/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/$theDiskUUID/System/Library/CoreServices"
    elif [[ $theletter == 'D' ]] && [[ -d "$MountPoint/System/Library/CoreServices" ]]; then
    if [[ $theletter == '' ]] && [[ -d "$MountPoint/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/System/Library/CoreServices"
    elif [[ $theletter == 'R' ]] && [[ -f "$MountPoint/$theDiskUUID/boot.efi" ]]; then
    elif [[ $theletter == '🄳' ]] && [[ -d "$MountPoint/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/System/Library/CoreServices"
    elif [[ $theletter == '🄿' ]] && [[ -d "$MountPoint/$theDiskUUID/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/$theDiskUUID/System/Library/CoreServices"
    elif [[ $theletter == '🅁' ]] && [[ -f "$MountPoint/$theDiskUUID/boot.efi" ]]; then
    thedest="${MountPoint}/${theDiskUUID}"
    if [[ -f "$thedest/boot.efi" ]]; then
    echo "# Blessing $thedest/boot.efi"
    sudo bless --folder "$thedest" --file "$thedest/boot.efi"
    fi
    fi

    local version=""
    local theversionfile="$thedest/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi

    if [[ -n "$thedest" ]]; then
    if [[ -n "$version" ]]; then
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${version} ${theletter}"
    else
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${theletter}"
    fi

    echo "# ${theline1} ${theline2}: Destination for ${theletter} $thedevice $thedest"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags noschg {} \;
    sudo cp /tmp/disklabeltemp/.disk_label* "$thedest"
    @@ -215,48 +218,38 @@ mountPrebootPartitions() {


    dumpAllDiskLabels () {
    # Partitions need to be mounted first.

    # Only includes Apple_HFS and Apple_Boot partitions.
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +Apple_[HFSBoot]* ([^ ].*[^ ]) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local version=""
    local mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
    local theblessinfo="$(bless --info "$mountpoint")"
    local thefolder=""
    local thefile=""
    local theopen=""
    eval $(echo "$theblessinfo" | sed -nE '/^finderinfo\[0\]: +[0-9]+ => Blessed System Folder is (.*)/s//thefolder="\1"/p; /^finderinfo\[1\]: +[0-9]+ => Blessed System File is (.*)/s//thefile="\1"/p; /^finderinfo\[2\]: +[0-9]+ => 1st dir in open-folder list is (.*)/s//theopen="\1"/p; ')
    if [[ -n $thefile ]]; then
    thefolder="$(dirname "$thefile")"
    if [[ "$thefolder" != /Volumes/*/System/Library/CoreServices ]]; then
    for theslice in $(diskutil list | sed -nE '/.*(disk[0-9]+s[0-9]+)$/s//\1/p'); do
    #echo $theslice
    diskutil mount $theslice > /dev/null 2>&1
    local MountPoint=""
    getdiskinfo $theslice
    if [[ -n "$MountPoint" ]]; then
    echo "#==========="
    echo $DeviceIdentifier $MountPoint

    local theblessinfo="$(bless --info "$MountPoint")"
    local theblessfolder=""
    local theblessfile=""
    local theopen=""
    eval $(echo "$theblessinfo" | sed -nE '/^finderinfo\[0\]: +[0-9]+ => Blessed System Folder is (.*)/s//theblessfolder="\1"/p; /^finderinfo\[1\]: +[0-9]+ => Blessed System File is (.*)/s//theblessfile="\1"/p; /^finderinfo\[2\]: +[0-9]+ => 1st dir in open-folder list is (.*)/s//theopen="\1"/p; ')
    if [[ -n $theblessfile ]]; then
    theblessfolder="$(dirname "$theblessfile")"
    fi

    for thefolder in $( { ls -d "$MountPoint/"*"/boot.efi" | sed -E '/\/boot.efi$/s///'; ls -d "$MountPoint/"*"/System/Library/CoreServices"; ls -d "$theblessfolder" "$MountPoint/System/Library/CoreServices" "$MountPoint/EFI/BOOT" } 2> /dev/null | sort -u ); do
    local version=""
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi
    echo "#$slice=$thefolder, $volume ($version)"
    echo "${thefolder} ($version)"
    [[ -f $thefolder/.disk_label_2x ]] && dump_label "$thefolder/.disk_label_2x" || echo " missing .disk_label_2x"
    [[ -f $thefolder/.disk_label ]] && dump_label "$thefolder/.disk_label" || echo " missing .disk_label"
    fi
    fi
    done

    # Scan the usual places first
    IFS=$'\n'
    for thefolder in $(find /Volumes/*/System/Library/CoreServices /Volumes/*/EFI/BOOT -maxdepth 0); do
    local volume=""
    local version=""
    volume="${thefolder/\/Volumes\//}"
    volume="${volume/\/System\/Library\/CoreServices/}"
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    done
    fi
    echo "#$thefolder ($version)"
    [[ -f $thefolder/.disk_label_2x ]] && dump_label "$thefolder/.disk_label_2x" || echo " missing .disk_label_2x"
    [[ -f $thefolder/.disk_label ]] && dump_label "$thefolder/.disk_label" || echo " missing .disk_label"
    done
    }
    @@ -336,6 +329,14 @@ getdiskinfo () {
    }
    showdiskinfo () {
    # $1 = the disk you want info for (either a mountpoint like "/" or a device "disk0s1")
    # $2 = prefix for variable names
    # note: you should clear any variables you want to use from this result beforehand
    diskutil info -plist $1 | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'$2'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }'
    }
    setbootername () {
    local thedisk="$1"
    local NewBooterName="$2"
  18. joevt created this gist Sep 30, 2020.
    373 changes: 373 additions & 0 deletions DiskUtil.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,373 @@
    # by joevt Sep 30, 2020

    # dump disk_label file
    dump_label () { local contents=$(xxd -p -c99999 "$1"); echo ${contents:10} | perl -pe "s/(..)/\1 /g;s/00/../g;s/ //g;s/(.{$((0x${contents:2:4}*2))})/\1\n/g" ; }


    # mount a partition
    mountpartition() {
    local mounttype=$1
    local slice=$2
    local volume=$3
    local mountpoint=$(mount | sed -n -E "/\/dev\/$slice on (.*) \(.*/s//\1/p")
    if [ -z $mountpoint ]; then
    i=0
    local startmountpoint="/Volumes/$volume"
    mountpoint="$startmountpoint"
    while [ -d "$mountpoint" ]; do
    ((i++))
    mountpoint="$startmountpoint$i"
    done
    fi
    if [ ! -d "$mountpoint" ]; then
    sudo mkdir "$mountpoint" 2> /dev/null
    sudo mount$mounttype "/dev/$slice" "$mountpoint"
    fi
    echo -n "$mountpoint"
    }


    makemultilinedisklabel () {
    local folder="$1"
    local lines="$2"
    local alllines=""
    local alllines2x=""

    [[ -d "/tmp/$folder" ]] || mkdir -p "/tmp/$folder"

    IFS=$'\n'
    local linenum=0
    local theline=""
    for theline in $(echo "$lines"); do
    #echo "doing line: \"$theline\""
    #echo sudo bless --folder "$folder" --label "$theline"
    sudo bless --folder "/tmp/$folder" --label "$theline" 2> /dev/null
    if (( $linenum )); then
    alllines+="$(dump_label "/tmp/$folder/.disk_label" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    alllines2x+="$(dump_label "/tmp/$folder/.disk_label_2x" | sed '1,/[^.]/ {/^[.]*$/d; }')"$'\n'
    else
    alllines+="$(dump_label "/tmp/$folder/.disk_label")"$'\n'
    alllines2x+="$(dump_label "/tmp/$folder/.disk_label_2x")"$'\n'
    fi
    ((linenum++))
    done

    local suffix=""
    local thelines=""
    for suffix in "" "_2x"; do
    [[ -z $suffix ]] && thelines="$alllines" || thelines="$alllines2x"

    local linewidths="$(echo "${thelines}" | tr '0-9a-f' '.' | sort -ur)"
    local maxlinewidth=$(echo "$linewidths" | sed -n '1p')
    linewidths=$(echo "$linewidths" | sed '1d')

    local centercommands=""
    local linewidth=""
    for linewidth in $(echo "$linewidths"); do
    local left=${maxlinewidth:0:(${#maxlinewidth}-${#linewidth})/4*2}
    local right=${maxlinewidth:0:(${#maxlinewidth}-${#linewidth}-${#left})}
    centercommands+="s/^(${linewidth})$/$left\1$right/; "
    done
    thelines=$(echo "$thelines" | sed -E "$centercommands s/\./0/g")
    printf "01%04x%04x$thelines" $((${#maxlinewidth} / 2)) $(echo "$thelines" | wc -l) | xxd -p -r > "/tmp/$folder/disk_label$suffix"

    [[ -f "$folder/.disk_label$suffix" ]] && sudo chflags noschg "$folder/.disk_label$suffix"
    sudo cp "/tmp/$folder/disk_label$suffix" "$folder/.disk_label$suffix"
    sudo chflags schg "$folder/.disk_label$suffix"
    [[ -f $folder/.disk_label.contentDetails ]] && sudo touch $folder/.disk_label.contentDetails
    #sudo bless --folder "$folder" --labelfile "/tmp/$folder/disk_label$suffix"
    #dump_label "$folder/.disk_label$suffix"
    done
    }


    fixapfsbooter () {
    local theosmountpoint="$1"
    local theline1="$2"
    local theline2="$3"

    if [[ -d "$theosmountpoint/System/Library/CoreServices" ]]; then
    mkdir -p /tmp/disklabeltemp
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1}"$'\n'"${theline2}"
    #open /tmp/disklabeltemp
    #dump_label /private/tmp/disklabeltemp/.disk_label_2x
    sudo cp /tmp/disklabeltemp/.disk_label* "$theosmountpoint/System/Library/CoreServices"
    [[ -f "$theosmountpoint/System/Library/CoreServices/.disk_label.contentDetails" ]] && sudo rm "$theosmountpoint/System/Library/CoreServices/.disk_label.contentDetails"
    #sudo echo -n "${theline1} ${theline2}" > "$theosmountpoint/System/Library/CoreServices/.disk_label.contentDetails"
    #open "$theosmountpoint/System/Library/CoreServices"

    local DiskUUID=""
    local APFSContainerReference=""
    local BooterDeviceIdentifier=""
    local RecoveryDeviceIdentifier=""
    getdiskinfo $theosmountpoint
    local theDiskUUID=$DiskUUID
    local theBooterDeviceIdentifier="$BooterDeviceIdentifier"
    local theRecoveryDeviceIdentifier="$RecoveryDeviceIdentifier"
    local theDataDeviceIdentifier=""
    local theAPFSContainerReference="$APFSContainerReference"

    if [[ -n $theAPFSContainerReference ]]; then
    local theDataDeviceIdentifier=$(diskutil apfs list $theAPFSContainerReference | perl -nE '/^[| ]*APFS Volume Disk \(Role\): *(disk\d+s\d+) *\(Data\)/ && print $1')
    fi

    if [[ -L "$theosmountpoint/.VolumeIcon.icns" ]]; then
    echo "Icon is sym link"
    cp -p "$theosmountpoint/.VolumeIcon.icns" /tmp/disklabeltemp
    sudo rm "$theosmountpoint/.VolumeIcon.icns"
    sudo cp -p /tmp/disklabeltemp/.VolumeIcon.icns "$theosmountpoint"
    fi

    for theitem in "P:$theBooterDeviceIdentifier" "R:$theRecoveryDeviceIdentifier" "D:$theDataDeviceIdentifier"; do
    local theletter="${theitem:0:1}"
    local thedevice="${theitem:2}"
    #echo $theletter
    #echo $thedevice

    if [[ -n $thedevice ]]; then
    diskutil mount $thedevice > /dev/null
    local MountPoint=""
    getdiskinfo $thedevice
    #echo $MountPoint
    if [[ -n $MountPoint ]]; then
    #open "$MountPoint"
    [[ -f "$theosmountpoint/.VolumeIcon.icns" ]] && sudo cp "$theosmountpoint/.VolumeIcon.icns" "$MountPoint" || echo "No volume icon to copy to $theitem"
    makemultilinedisklabel "/tmp/disklabeltemp" "${theline1} (${theletter})"$'\n'"${theline2}"
    #open "/tmp/disklabeltemp"
    #dump_label /tmp/disklabeltemp/.disk_label_

    local thedest=""

    if [[ $theletter == 'P' ]] && [[ -d "$MountPoint/$theDiskUUID/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/$theDiskUUID/System/Library/CoreServices"
    elif [[ $theletter == 'D' ]] && [[ -d "$MountPoint/System/Library/CoreServices" ]]; then
    thedest="$MountPoint/System/Library/CoreServices"
    elif [[ $theletter == 'R' ]] && [[ -f "$MountPoint/$theDiskUUID/boot.efi" ]]; then
    thedest="${MountPoint}/${theDiskUUID}"
    if [[ -f "$thedest/boot.efi" ]]; then
    echo "# Blessing $thedest/boot.efi"
    sudo bless --folder "$thedest" --file "$thedest/boot.efi"
    fi
    fi

    if [[ -n "$thedest" ]]; then
    echo "# ${theline1} ${theline2}: Destination for ${theletter} $thedevice $thedest"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags noschg {} \;
    sudo cp /tmp/disklabeltemp/.disk_label* "$thedest"
    sudo find "$thedest" -name '.disk_label*' -not -name '*.contentDetails' -exec chflags schg {} \;
    [[ -f "$thedest/.disk_label.contentDetails" ]] && sudo rm "$thedest/.disk_label.contentDetails"
    #sudo echo -n "${theline1} (${theletter}) ${theline2}" > "$thedest/.disk_label.contentDetails"
    else
    echo "# ${theline1} ${theline2}: No destination for ${theletter} $thedevice $MountPoint"
    fi
    fi
    fi
    done
    fi
    }


    getvolumename () {
    local slice="$1"
    eval "$(diskutil info -plist /dev/$slice | plutil -p - | sed -nE '/^ *"VolumeName" => (.*)/s//echo \1/p')"
    }


    mountEFIpartitions () {
    IFS=$'\n'
    local diskinfo=""
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +EFI (.*[^ ]) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_msdos" "$slice" "$volume" > /dev/null
    done
    }


    mountRecoveryHDpartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +Apple_Boot (Recovery HD) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_hfs" "$slice" "$volume" > /dev/null
    done
    }


    mountRecoveryPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +APFS Volume (Recovery) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_apfs" "$slice" "$volume" > /dev/null
    done
    }


    mountPrebootPartitions() {
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +APFS Volume (Preboot) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    mountpartition "_apfs" "$slice" "$volume" > /dev/null
    done
    }


    dumpAllDiskLabels () {
    # Partitions need to be mounted first.

    # Only includes Apple_HFS and Apple_Boot partitions.
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +Apple_[HFSBoot]* ([^ ].*[^ ]) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local version=""
    local mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
    local theblessinfo="$(bless --info "$mountpoint")"
    local thefolder=""
    local thefile=""
    local theopen=""
    eval $(echo "$theblessinfo" | sed -nE '/^finderinfo\[0\]: +[0-9]+ => Blessed System Folder is (.*)/s//thefolder="\1"/p; /^finderinfo\[1\]: +[0-9]+ => Blessed System File is (.*)/s//thefile="\1"/p; /^finderinfo\[2\]: +[0-9]+ => 1st dir in open-folder list is (.*)/s//theopen="\1"/p; ')
    if [[ -n $thefile ]]; then
    thefolder="$(dirname "$thefile")"
    if [[ "$thefolder" != /Volumes/*/System/Library/CoreServices ]]; then
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi
    echo "#$slice=$thefolder, $volume ($version)"
    [[ -f $thefolder/.disk_label_2x ]] && dump_label "$thefolder/.disk_label_2x" || echo " missing .disk_label_2x"
    [[ -f $thefolder/.disk_label ]] && dump_label "$thefolder/.disk_label" || echo " missing .disk_label"
    fi
    fi
    done

    # Scan the usual places first
    IFS=$'\n'
    for thefolder in $(find /Volumes/*/System/Library/CoreServices /Volumes/*/EFI/BOOT -maxdepth 0); do
    local volume=""
    local version=""
    volume="${thefolder/\/Volumes\//}"
    volume="${volume/\/System\/Library\/CoreServices/}"
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi
    echo "#$thefolder ($version)"
    [[ -f $thefolder/.disk_label_2x ]] && dump_label "$thefolder/.disk_label_2x" || echo " missing .disk_label_2x"
    [[ -f $thefolder/.disk_label ]] && dump_label "$thefolder/.disk_label" || echo " missing .disk_label"
    done
    }


    makeLabelCommands () {
    # Partitions need to be mounted first.

    # Only includes Apple_HFS and Apple_Boot partitions.
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +Apple_[HFSBoot]* ([^ ].*[^ ]) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local version=""
    local mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
    local theblessinfo="$(bless --info "$mountpoint")"
    local thefolder=""
    local thefile=""
    local theopen=""
    eval $(echo "$theblessinfo" | sed -nE '/^finderinfo\[0\]: +[0-9]+ => Blessed System Folder is (.*)/s//thefolder="\1"/p; /^finderinfo\[1\]: +[0-9]+ => Blessed System File is (.*)/s//thefile="\1"/p; /^finderinfo\[2\]: +[0-9]+ => 1st dir in open-folder list is (.*)/s//theopen="\1"/p; ')
    if [[ -n $thefile ]]; then
    thefolder="$(dirname "$thefile")"
    if [[ "$thefolder" != /Volumes/*/System/Library/CoreServices ]]; then
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi
    echo "#$slice=$thefolder, $volume ($version)"
    printf 'makemultilinedisklabel "%s" "%s"$%c\\n%c"%s"\n' "$thefolder" "${volume/Recovery HD/Recovery}" "'" "'" "$version"
    fi
    fi
    done

    # Scan the usual places first
    IFS=$'\n'
    for thefolder in $(find /Volumes/*/System/Library/CoreServices /Volumes/*/EFI/BOOT -maxdepth 0); do
    local volume=""
    local version=""
    volume="${thefolder/\/Volumes\//}"
    volume="${volume/\/System\/Library\/CoreServices/}"
    local theversionfile="$thefolder/SystemVersion.plist"
    if [[ -f "$theversionfile" ]]; then
    version=$(/usr/libexec/PlistBuddy -c 'Print :ProductVersion' "$theversionfile")
    fi
    echo "#$thefolder ($version)"
    printf 'makemultilinedisklabel "%s" "%s"$%c\\n%c"%s"\n' "$thefolder" "${volume/Recovery HD/Recovery}" "'" "'" "$version"
    done
    }


    clearOpenFolders () {
    # Clear open folder list of hfs partitions (finderinfo[2] in bless --info).
    # If you have an HFS+ disk that has folders that open when you mount them (such as an installer), then this will stop that from happening.
    IFS=$'\n'
    for diskinfo in $(diskutil list | sed -nE '/^ *[0-9]+: +Apple_HFS (.*[^ ]) +[0-9.]+ [^ ]?B +(disk[0-9]+s[0-9]+)$/s//\1_\2/p'); do
    local slice="${diskinfo##*_}"
    local volume="$(getvolumename $slice)"
    local mountpoint=$(mountpartition "_hfs" "$slice" "$volume")
    echo "#$slice=$mountpoint,$volume ($version)"
    local theblessinfo="$(bless --info "$mountpoint")"
    local thefolder=""
    local thefile=""
    local theopen=""
    eval $(echo "$theblessinfo" | sed -nE '/^finderinfo\[0\]: +[0-9]+ => Blessed System Folder is (.*)/s//thefolder="\1"/p; /^finderinfo\[1\]: +[0-9]+ => Blessed System File is (.*)/s//thefile="\1"/p; /^finderinfo\[2\]: +[0-9]+ => 1st dir in open-folder list is (.*)/s//theopen="\1"/p; ')
    if [[ -n $theopen ]]; then
    echo "Clearing open folder list"
    sudo bless --folder "$thefolder" --file "$thefile"
    fi
    done
    }


    getdiskinfo () {
    # $1 = the disk you want info for (either a mountpoint like "/" or a device "disk0s1")
    # $2 = prefix for variable names
    # note: you should clear any variables you want to use from this result beforehand
    eval $(diskutil info -plist $1 | plutil -p - | perl -nE 'if (s/ *"([^"]+)" => "?(.*?)"?$/'$2'\1=\2/) { s/"/\\"/g; s/([^=]+=)(.*)/\1"\2"/; print $_ }')
    }


    setbootername () {
    local thedisk="$1"
    local NewBooterName="$2"

    getdiskinfo "$thedisk" Root
    if [[ -n $RootBooterDeviceIdentifier ]]; then
    diskutil mount $RootBooterDeviceIdentifier
    getdiskinfo $RootBooterDeviceIdentifier Preboot
    if [[ -n $PrebootMountPoint ]]; then
    local theUUID=""
    if [[ -d $PrebootMountPoint/$RootVolumeUUID ]]; then
    theUUID=$RootVolumeUUID
    echo "using VolumeUUID"
    elif [[ -d $PrebootMountPoint/$RootAPFSVolumeGroupID ]]; then
    theUUID=$RootAPFSVolumeGroupID
    echo "using APFSVolumeGroupID"
    else
    echo "unknown UUID in booter"
    ls -l "$PrebootMountPoint"
    return 1
    fi
    thefile="$PrebootMountPoint/$theUUID/System/Library/CoreServices/.disk_label.contentDetails"
    if [[ -f "$thefile" ]]; then
    echo "$thefile already exists: $(cat "$thefile")"
    else
    sudo bash -c "echo \"$NewBooterName\" > \"$thefile\""
    echo "$thefile is created"
    fi
    else
    echo "$RootBooterDeviceIdentifier is not mounted"
    fi
    else
    echo "No booter device"
    fi
    }