Skip to content

Instantly share code, notes, and snippets.

@scottsb
Forked from Hais/workspace.sh
Last active January 16, 2024 08:47
Show Gist options
  • Save scottsb/479bebe8b4b86bf17e2d to your computer and use it in GitHub Desktop.
Save scottsb/479bebe8b4b86bf17e2d to your computer and use it in GitHub Desktop.
Create and manage a case-sensitive disk-image on macOS (OS X).
#!/bin/bash
# ---------------------------------------------------------
# Customizable Settings
# ---------------------------------------------------------
MOUNT_POINT="${CASE_SAFE_MOUNT_POINT:-${HOME}/casesafe}"
VOLUME_PATH="${CASE_SAFE_VOLUME_PATH:-${HOME}/.casesafe.dmg.sparseimage}"
VOLUME_NAME="${CASE_SAFE_VOLUME_NAME:-casesafe}"
VOLUME_SIZE="${CASE_SAFE_VOLUME_SIZE:-60g}"
# ---------------------------------------------------------
# Functionality
# ---------------------------------------------------------
create() {
hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size ${VOLUME_SIZE} -volname ${VOLUME_NAME} ${VOLUME_PATH}
}
automount() {
attach
cat << EOF > "/tmp/com.${VOLUME_NAME}.plist"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>RunAtLoad</key>
<true/>
<key>Label</key>
<string>com.${VOLUME_NAME}</string>
<key>ProgramArguments</key>
<array>
<string>hdiutil</string>
<string>attach</string>
<string>-notremovable</string>
<string>-nobrowse</string>
<string>-mountpoint</string>
<string>${MOUNT_POINT}</string>
<string>${VOLUME_PATH}</string>
</array>
</dict>
</plist>
EOF
sudo cp "/tmp/com.${VOLUME_NAME}.plist" "/Library/LaunchDaemons/com.${VOLUME_NAME}.plist"
rm "/tmp/com.${VOLUME_NAME}.plist"
}
noautomount() {
detach
sudo rm -f "/Library/LaunchDaemons/com.${VOLUME_NAME}.plist"
}
detach() {
m=$(hdiutil info | grep "${MOUNT_POINT}" | cut -f1)
if [ ! -z "$m" ]; then
sudo hdiutil detach $m
fi
}
attach() {
sudo hdiutil attach -notremovable -nobrowse -mountpoint ${MOUNT_POINT} ${VOLUME_PATH}
}
resize() {
compact
detach
hdiutil resize -size ${VOLUME_SIZE} ${VOLUME_PATH}
attach
}
compact() {
detach
hdiutil compact ${VOLUME_PATH} -batteryallowed
attach
}
help() {
cat <<EOF
usage: casesafe <command>
Possible commands:
create Initialize case-sensitive volume (only needed first time)
automount Configure macOS to mount the volume automatically on restart
noautomount Stop macOS from mounting the volume automatically on restart
mount Attach the case-sensitive volume
unmount Detach the case-sensitive volume
resize Resize the case-sensitive volume
compact Remove any uneeded reserved space in the volume
config Show current configuration and instructions on changing
help Display this message
EOF
}
config() {
cat <<EOF
The behavior of the script may be modified by setting the following environment variables.
If not set the script will use sane defaults.
CASE_SAFE_MOUNT_POINT
Location where case-sensitive volume will be mounted
Current effective value: ${MOUNT_POINT}
CASE_SAFE_VOLUME_PATH
Location where image file should be stored
Current effective value: ${VOLUME_PATH}
CASE_SAFE_VOLUME_NAME
Name of case-sensitive workspace as visible in macOS Finder app
Current effective value: ${VOLUME_NAME}
CASE_SAFE_VOLUME_SIZE
Maximum size of volume (will auto-grow up to this)
Current effective value: ${VOLUME_SIZE}
EOF
}
invalid() {
printf "casesafe: '$1' is not a valid command.\n\n";
help
}
case "$1" in
create) create;;
automount) automount;;
noautomount) noautomount;;
mount) attach;;
unmount) detach;;
resize) resize;;
compact) compact;;
config) config;;
help) help;;
'') help;;
*) invalid $1;;
esac
@REBELinBLUE
Copy link

For anyone who comes here, I was having the IO issues @tpinne mentioned but as my previous comment indicated I have only been having them since using Big Sur. I have changed the script so that the filesystem is "Case-sensitive APFS" and so far it seems a lot better... I was barely able to run npm install in directories in the mounted workspace before, now it seems to be working as expected

@convenient
Copy link

Any ideas on how to encrypt this?

I tried to add hdiutil create -encryption flag and enter a password etc, it works properly when I manually mount it but then when I run

hdiutil isencrypted /dev/disk3s1
encrypted: NO

It says not encrypted 🤔 not sure if i'm not thinkin something through properly though

@scottsb
Copy link
Author

scottsb commented Aug 8, 2021

Unfortunately, I am no longer using this myself, so I can't advise much. I did do a quick search and found this:
https://apple.stackexchange.com/a/178685

That answer specifically mentions Maverisks so is rather old, but if I'm reading it correctly, it sounds like it's possible for macOS to cache an old encryption status of "no" if a drive with the same path/name is remounted as one that was previously encrypted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment