Last active
June 4, 2023 22:35
-
-
Save JayBrown/da7da1ef88cdce264fb47495a0fd34c4 to your computer and use it in GitHub Desktop.
Ejecta: correctly eject APFS-formatted DMGs (raw version)
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/zsh | |
# shellcheck shell=bash | |
# ejecta v0.11 | |
# https://gist.github.com/JayBrown/da7da1ef88cdce264fb47495a0fd34c4 | |
export PATH=/usr/bin:/usr/sbin:/bin:/sbin | |
_beep () { | |
osascript -e 'beep' -e 'delay 0.5' &>/dev/null | |
} | |
for filepath in "$@" | |
do | |
echo "Input: $filepath" | |
apfs=false | |
device_all=$(df "$filepath" | grep "^/") | |
if [[ $device_all == "//"* ]] ; then | |
device1=$(echo "$device_all" | awk '{print substr($0, index($0,$9))}') | |
devinfo=$(echo "$device_all" | awk '{print $1}') | |
echo "Target: $device1 ($devinfo)" | |
if [[ -f "$device_path/.volume_never_unmount" ]] ; then | |
echo "Volume blocked!" | |
_beep | |
continue | |
fi | |
else | |
if [[ $(echo "$device_all" | awk '{print $NF}') == "/" ]] ; then | |
echo -e "Target: /\nInternal volume blocked by default!" | |
_beep | |
continue | |
fi | |
device_path=$(echo "$device_all" | awk '{print substr($0, index($0,$9))}') | |
if [[ $device_path == "/System/Volumes/Data" ]] ; then | |
echo -e "Target: /System/Volumes/Data\nInternal volume blocked by default!" | |
_beep | |
continue | |
fi | |
echo "Target: $device_path" | |
if [[ -f "$device_path/.volume_never_unmount" ]] ; then | |
echo "Volume blocked!" | |
_beep | |
continue | |
fi | |
device1=$(echo "$device_all" | awk '{print $1}') | |
dev1info=$(diskutil list "$device1") | |
vol1info=$(echo "$dev1info" | grep "$device1$") | |
echo "$vol1info" | grep -q "APFS" &>/dev/null && apfs=true | |
device1=$(echo "$dev1info" | head -1 | awk '{print $1}') | |
echo "Target device: $device1" | |
fi | |
if ! $apfs ; then | |
echo "Volume is not APFS-formatted: detaching..." | |
hdiutil detach "$device1" | |
else | |
echo "Volume is APFS-formatted" | |
dev2info=$(echo "$dev1info" | grep "Physical Store") | |
dev2base=$(echo "$dev2info" | awk -F"Physical Store " '{print $2}') | |
dev2path="/dev/$dev2base" | |
device2=$(diskutil list "$dev2path" | head -1 | awk '{print $1}') | |
echo -e "Secondary target device: $device2\nDetaching all..." | |
hdiutil detach "$device1" && hdiutil detach "$device2" | |
fi | |
done | |
exit |
v0.11: additional checks for local SMB-mounted volumes with leading //
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
v0.10: now with more checks, incl. internal volumes plus a check for a
.volume_never_unmount
dotfile in the volume's root.