|
# ramdisk: create or destroy a macOS APFS RAM disk |
|
ramdisk() { |
|
local cmd size blocks device backing mp="/Volumes/RAMDisk" |
|
|
|
# validate command |
|
if [[ $1 != create && $1 != destroy ]]; then |
|
echo "Usage: ramdisk create <size_in_GiB> | destroy" >&2 |
|
return 1 |
|
fi |
|
cmd=$1 |
|
|
|
# Create |
|
if [[ $cmd == create ]]; then |
|
# require exactly two args |
|
if (( $# != 2 )); then |
|
echo "Usage: ramdisk create <size_in_GiB>" >&2 |
|
return 1 |
|
fi |
|
|
|
# numeric check (digits only) |
|
if ! [[ $2 =~ ^[0-9]+$ ]]; then |
|
echo "Error: size must be an integer (no letters or symbols)" >&2 |
|
return 1 |
|
fi |
|
|
|
# strip leading zeros and convert to number |
|
size=$((10#$2)) |
|
|
|
# enforce range 1โ128 GiB |
|
if (( size < 1 || size > 128 )); then |
|
echo "Error: size must be between 1 and 128 GiB" >&2 |
|
return 1 |
|
fi |
|
|
|
# prevent duplicate mount |
|
if [[ -d $mp ]]; then |
|
echo "Error: RAMDisk already exists at $mp" >&2 |
|
return 1 |
|
fi |
|
|
|
# calculate block count (GiB ร 2^21 blocks of 512 bytes) |
|
blocks=$(( size * 2097152 )) |
|
|
|
echo "โ Attaching ram://$blocks (512-byte blocks โ ${size}GiB)โฆ" |
|
device=$(hdiutil attach -nomount ram://$blocks 2>/dev/null \ |
|
| awk '/^\/dev/{print $1; exit}') || { |
|
echo "Error: hdiutil attach failed" >&2 |
|
return 1 |
|
} |
|
echo " โ assigned device: $device" |
|
|
|
echo "โ Creating APFS container & volume 'RAMDisk' on $deviceโฆ" |
|
diskutil apfs create "$device" RAMDisk >/dev/null || { |
|
echo "Error: formatting failed" >&2 |
|
hdiutil detach "$device" -force >/dev/null |
|
return 1 |
|
} |
|
echo " โ volume 'RAMDisk' mounted at $mp" |
|
|
|
echo "โ RAMDisk (${size}GiB) ready at $mp (device: $device)" |
|
return 0 |
|
fi |
|
|
|
# Destroy |
|
if [[ $cmd == destroy ]]; then |
|
# no extra args |
|
if (( $# != 1 )); then |
|
echo "Usage: ramdisk destroy" >&2 |
|
return 1 |
|
fi |
|
|
|
# must be mounted |
|
if [[ ! -d $mp ]]; then |
|
echo "Error: no RAMDisk found at $mp" >&2 |
|
return 1 |
|
fi |
|
|
|
echo "โ Locating device for $mpโฆ" |
|
device=$(df "$mp" 2>/dev/null | awk 'NR==2{print $1}') || { |
|
echo "Error: cannot determine device for $mp" >&2 |
|
return 1 |
|
} |
|
echo " โ device is $device" |
|
|
|
echo "โ Unmounting $mp" |
|
diskutil unmount "$mp" >/dev/null || { echo "Error: unmount failed" >&2; return 1; } |
|
|
|
# find the RAM-backing device (Physical Store of the APFS container) |
|
echo "โ Finding backing store for ${device%s*}โฆ" |
|
backing=$(diskutil info "${device%s*}" \ |
|
| awk '/Physical Store/{print $NF; exit}') || { |
|
echo "Error: cannot determine backing device" >&2 |
|
return 1 |
|
} |
|
echo " โ backing device is /dev/$backing" |
|
|
|
echo "โ Detaching /dev/$backing" |
|
hdiutil detach "/dev/$backing" >/dev/null || { echo "Error: eject failed" >&2; return 1; } |
|
|
|
echo "โ RAMDisk at $mp destroyed" |
|
return 0 |
|
fi |
|
} |