Initial commit
This commit is contained in:
commit
0cd1cbb132
7 changed files with 148 additions and 0 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2025 Pipo
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
46
README.md
Normal file
46
README.md
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# auto-snapclean-listener
|
||||
|
||||
A small macOS utility script that automatically deletes all local Time Machine snapshots once they are created.
|
||||
It is useful for users who do not want macOS to keep local snapshots and prefer to rely only on external Time Machine backups.
|
||||
|
||||
⚠️ Tested on **macOS Tahoe**. Other versions may work, but are not guaranteed.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
- Listens for local Time Machine snapshot creation events.
|
||||
- Waits until the backup process is finished (avoids conflicts).
|
||||
- Automatically deletes all local snapshots afterwards.
|
||||
- Lightweight: no constant polling, event-driven.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/YOURUSERNAME/auto-snapclean-listener.git
|
||||
cd auto-snapclean-listener
|
||||
```
|
||||
|
||||
Make the script executable:
|
||||
|
||||
```bash
|
||||
chmod +x auto-snapclean-listener.sh
|
||||
```
|
||||
|
||||
Install the LaunchDaemon:
|
||||
|
||||
```bash
|
||||
sudo cp auto-snapclean-listener.plist /Library/LaunchDaemons/
|
||||
sudo launchctl load /Library/LaunchDaemons/auto-snapclean-listener.plist
|
||||
```
|
||||
|
||||
Uninstall (if needed):
|
||||
|
||||
```bash
|
||||
sudo launchctl unload /Library/LaunchDaemons/auto-snapclean-listener.plist
|
||||
sudo rm /Library/LaunchDaemons/auto-snapclean-listener.plist
|
||||
```
|
||||
15
launchd/com.snapclean.listener.plist
Normal file
15
launchd/com.snapclean.listener.plist
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?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>Label</key><string>com.snapclean.listener</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/local/bin/auto-snapclean-listener.sh</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key><true/>
|
||||
<key>KeepAlive</key><true/>
|
||||
<key>UserName</key><string>root</string>
|
||||
</dict>
|
||||
</plist>
|
||||
43
scripts/auto-snapclean-listener.sh
Normal file
43
scripts/auto-snapclean-listener.sh
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#!/bin/zsh
|
||||
set -euo pipefail
|
||||
|
||||
LOGF="/var/log/snapclean.log"
|
||||
log() { print -r -- "$(date '+%F %T') $*" >> "$LOGF"; }
|
||||
|
||||
is_running() {
|
||||
/usr/bin/tmutil status 2>/dev/null | /usr/bin/grep -Eq '"Running" = 1|Running = 1'
|
||||
}
|
||||
|
||||
wait_until_tm_idle() {
|
||||
local i=0
|
||||
while is_running; do
|
||||
sleep 2
|
||||
(( i++ ))
|
||||
[[ $i -gt 150 ]] && log "Timeout: TM still running. Waiting until it's finished." && break
|
||||
done
|
||||
}
|
||||
|
||||
delete_all_snapshots() {
|
||||
log "Deletes all local Snapshots at / …"
|
||||
/usr/bin/tmutil deletelocalsnapshots / || true
|
||||
log "Finished deleting."
|
||||
}
|
||||
|
||||
# Make sure logfile exists
|
||||
[[ -f "$LOGF" ]] || { sudo touch "$LOGF"; sudo chmod 644 "$LOGF"; }
|
||||
|
||||
while IFS= read -r line; do
|
||||
if print -r -- "$line" | /usr/bin/grep -q \
|
||||
"com.apple.TimeMachine:LocalSnapshotManagement] Created Time Machine local snapshot"; then
|
||||
log "Event erkannt: $line"
|
||||
# Short break until the snapshot is in index
|
||||
sleep 2
|
||||
# Waiting until TM is finished
|
||||
wait_until_tm_idle
|
||||
# delete all local snapshots
|
||||
delete_all_snapshots
|
||||
fi
|
||||
done < <(
|
||||
/usr/bin/log stream --style syslog --level info \
|
||||
--predicate 'process == "backupd" AND subsystem == "com.apple.TimeMachine"'
|
||||
)
|
||||
17
scripts/install.sh
Normal file
17
scripts/install.sh
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/zsh
|
||||
set -euo pipefail
|
||||
|
||||
PLIST_SRC="$(cd -- "$(dirname "$0")/.." && pwd)/launchd/com.snapclean.listener.plist"
|
||||
SCRIPT_SRC="$(cd -- "$(dirname "$0")/.." && pwd)/scripts/auto-snapclean-listener.sh"
|
||||
|
||||
sudo install -m 0755 "$SCRIPT_SRC" /usr/local/bin/auto-snapclean-listener.sh
|
||||
sudo install -m 0644 "$PLIST_SRC" /Library/LaunchDaemons/com.snapclean.listener.plist
|
||||
sudo touch /var/log/snapclean.log /var/log/snapclean.out /var/log/snapclean.err
|
||||
sudo chmod 644 /var/log/snapclean.*
|
||||
|
||||
# (re)load
|
||||
sudo launchctl unload /Library/LaunchDaemons/com.snapclean.listener.plist 2>/dev/null || true
|
||||
sudo launchctl load -w /Library/LaunchDaemons/com.snapclean.listener.plist
|
||||
sudo launchctl list | grep snapclean || true
|
||||
|
||||
echo "✅ snapcleaner installed."
|
||||
6
scripts/uninstall.sh
Normal file
6
scripts/uninstall.sh
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/zsh
|
||||
set -euo pipefail
|
||||
sudo launchctl unload /Library/LaunchDaemons/com.snapclean.listener.plist 2>/dev/null || true
|
||||
sudo rm -f /Library/LaunchDaemons/com.snapclean.listener.plist
|
||||
sudo rm -f /usr/local/bin/auto-snapclean-listener.sh
|
||||
echo "✅ snapcleaner deleted. Logs stay in /var/log/snapclean.*"
|
||||
Loading…
Add table
Add a link
Reference in a new issue