-
-
Save joevt/6d7a0ede45106345a39bdfa0ac10ffd6 to your computer and use it in GitHub Desktop.
| # 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 | |
| } |
Big Sur changed the output format of the diskutil list command so it includes invisible surround characters before and after the volume name. I've updated the script to account for that.
I should probably move away from using diskutil list and use diskutil list -plist. The plist can be parsed as-is using plutil or PlistBuddy. Piping the plist to plutil -p - creates something that looks like perl hashes/arrays but it's missing commas and the arrays look like hashes but those two issues are simple to fix. The problem is that man plutil says the -p format is not stable and not designed for machine parsing. As an alternative, the plutil command can convert to JSON. Perl can convert JSON to hashes/arrays using the JSON::parse function.
I used the plutil with perl json method in the getallmounteddisks command to loop through all the disks.
Thanks for adding convert_label function.
It did not work for me as mentioned on insanelymac forum thread.
There's an error from tr :
tr: Illegal byte sequence
@MacNB fixed.
Perfect. Many thanks.
For Big Sur and later to write the labels to disk you may need to mount the system writable:
https://github.com/fxgst/writeable_root
True, but only the labels in the Preboot volume (and maybe the Recovery volume) actually matter and those are always writable I think.
The Data volume is not bootable (doesn't have boot.efi in /System/Library/CoreServices)
The System volume has a boot.efi but I don't think it's bootable.
I'll look into this one day when I get around to installing Big Sur and Monterey to my Mac Pro 2008.
One issue is that the .VolumeIcon.icns file on the System volume is a firm link to the icon on the Data volume. This makes the icon not viewable when booted into other macOS partitions so I'll probably want to fix that.
Here is the log:
mountPrebootPartitions
mbp113@MacBook-Pro ~ % dumpAllDiskLabels > dumpAllDiskLabels.txt
Can't get device for /Volumes/BOOTCAMP
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "<stdin>: Property Li...") at -e line 2.
mbp113@MacBook-Pro ~ % makeLabelCommands > makeLabelCommands.txt
mbp113@MacBook-Pro ~ % makemultilinedisklabel > makemultilinedisklabel.txt
cp: /.disk_label: Read-only file system
chflags: /.disk_label: No such file or directory
cp: /.disk_label_2x: Read-only file system
chflags: /.disk_label_2x: No such file or directory
cp: /.disk_label.contentDetails: Read-only file system
chflags: /.disk_label.contentDetails: No such file or directory
mbp113@MacBook-Pro ~ % sudo makemultilinedisklabel > makemultilinedisklabel.txt
sudo: makemultilinedisklabel: command not found
mbp113@MacBook-Pro ~ % getblessinfo > getblessinfo.txt
Can't get device for
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "<stdin>: Property Li...") at -e line 2.
mbp113@MacBook-Pro ~ % dumpAllDiskLabels > dumpAllDiskLabels1.txt
Can't get device for /Volumes/BOOTCAMP
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "<stdin>: Property Li...") at -e line 2.
Remove .png and rename to .zip the attachment.

Download
curl -L https://gist.github.com/joevt/6d7a0ede45106345a39bdfa0ac10ffd6/raw -o ~/Downloads/DiskUtil.shInstall (temporarily, only for the current terminal window)
Test
Make a list of commands that can be edited to create multi-line disk label files.
makeLabelCommandsMake a multi-line disk label file in a specific folder. Example:
makemultilinedisklabel "/Volumes/EFISATA/EFI/BOOT" "Ubuntu"$'\n'"22.04 LTS"Changes
May 10, 2023
makemultilinedisklabelso it creates the temp folder in /tmp/unsetallso it doesn't complain about non-utf8 characters.fixapfsbooterandunlockapfsbooterso they log System Volume UUID, No APFS Volume Group, or when it is assuming the System Volume UUID.dumpAllDiskLabelsso it checks /System/Library/CoreServices of root file system.May 23, 2022
unlockapfsbooterto unlock the disk label files created byfixapfsbooterwhich might cause problems for macOS updaters.Dec 24, 2021
Nov 30, 2021
getblessinfo(fixes issue with NTFS disks).makemultilinedisklabel. Note that most commands expect you to enter correct arguments.Both of those commands do not output results to stdout.
getblessinfoand other commands output results to variables (similar toeval "$(stat -s somepath)"instead of to stdout.sudodoes not work with shell function variables such as these commands or built in shell commands likeif.