-
-
Save briantully/e3c422d18f7ff1bc1699edaf46c954c8 to your computer and use it in GitHub Desktop.
macOS disk labels, mounting partitions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# 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 | |
# 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" ; } | |
# mount a partition | |
mountpartition() { | |
local mounttype=$1 | |
local slice=$2 | |
local volume=$3 | |
local mountpoint="" | |
mountpoint=$(mount | sed -n -E "/\/dev\/$slice on (.*) \(.*/s//\1/p") | |
if [[ -n "$mountpoint" ]]; then | |
echo -n "$mountpoint" | |
return 0 | |
fi | |
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 $? | |
} | |
makemultilinedisklabel () { | |
local folder="$1" | |
local lines="$2" | |
local alllines="" | |
local alllines2x="" | |
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 | |
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 | |
local suffix="" | |
local thelines="" | |
for suffix in "" "_2x"; do | |
[[ -z $suffix ]] && thelines="$alllines" || thelines="$alllines2x" | |
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="" | |
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 > "$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" | |
#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]}" | |
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" | |
} | |
unsetall () { | |
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" | |
if [[ -z $theoneapfsmountpoint ]]; then | |
echo "#Error: missing parameters" | |
return 1 | |
fi | |
if [[ -z $theline1 ]]; then | |
echo "#Error: missing second parameter" | |
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 | |
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 | |
local Recovery_MountPoint="" | |
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 | |
local issource=0 | |
if [[ "$diskutil_fab2_MountPoint" == "$diskutil_fab1_MountPoint" ]]; then | |
issource=1 | |
fi | |
local theletter="" | |
local thedest="" | |
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 | |
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}" | |
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 | |
echo "# Destination does not exist $thedest" | |
fi | |
fi # if mount | |
fi # if the disk | |
done # for thedisk | |
done # for thepass | |
echo "#================" | |
echo "# Done!" | |
} | |
getvolumeproperty () { | |
local slice="$1" | |
local property="$2" | |
eval "$(diskutil info -plist "$slice" | plutil -p - | sed -nE '/^ *"'"$property"'" => (.*)/s//echo \1/p')" | |
} | |
getvolumename () { | |
getvolumeproperty "$1" "VolumeName" | |
} | |
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 | |
local slice="${diskinfo##*_}" | |
local volume="" | |
volume="$(getvolumename "$slice")" | |
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 | |
local slice="${diskinfo##*_}" | |
local volume="" | |
volume="$(getvolumename "$slice")" | |
mountpartition "_hfs" "$slice" "$volume" > /dev/null | |
done | |
} | |
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="" | |
volume="$(getvolumename "$slice")" | |
mountpartition "_apfs" "$slice" "$volume" > /dev/null | |
done | |
} | |
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="" | |
volume="$(getvolumename "$slice")" | |
mountpartition "_apfs" "$slice" "$volume" > /dev/null | |
done | |
} | |
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"})')" | |
} | |
dumpAllDiskLabels () { | |
IFS=$'\n' | |
for theslice in $(diskutil list | sed -nE '/.*(disk[0-9]+s[0-9]+)$/s//\1/p'); do | |
#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 theblessfolder="" | |
local theblessfile="" | |
local theblessopen="" | |
getblessinfo "$diskutil_dadl_MountPoint" | |
if [[ -n $theblessfile ]]; then | |
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 | |
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 | |
fi | |
done | |
} | |
makeLabelCommands () { | |
# Partitions need to be mounted first. | |
# 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="" | |
volume="$(getvolumename "$slice")" | |
local version="" | |
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 | |
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/\/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 | |
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 | 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="" | |
volume="$(getvolumename "$slice")" | |
local mountpoint="" | |
mountpoint=$(mountpartition "_hfs" "$slice" "$volume") | |
echo "#$slice=$mountpoint,$volume ($version)" | |
local theblessfolder="" | |
local theblessfile="" | |
local theblessopen="" | |
getblessinfo "$mountpoint" | |
if [[ -n $theblessopen ]]; then | |
echo "Clearing open folder list" | |
sudo "$directbless" --folder "$theblessfolder" --file "$theblessfile" | |
fi | |
done | |
} | |
getdiskinfo () { | |
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 "$(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 $_ }' | |
} | |
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 =~ $patVolumeGroup ]]; then | |
getdiskinfo "${theapfsvolume#*=}" "diskutil_role_" | |
fi | |
echo "${diskutil_role_APFSVolumeGroupID}_${theapfsvolume}" | |
done | |
} | |
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" | |
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 | |
theUUID=$diskutil_sbn_Root_VolumeUUID | |
echo "using VolumeUUID" | |
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 "$diskutil_sbn_Preboot_MountPoint" | |
return 1 | |
fi | |
local 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 "$diskutil_sbn_Root_BooterDeviceIdentifier is not mounted" | |
fi | |
else | |
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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment