Skip to content

Instantly share code, notes, and snippets.

@rainrisa
Created May 16, 2025 02:53
Show Gist options
  • Select an option

  • Save rainrisa/1ef61d8f42f16eb942b6e7fefe673112 to your computer and use it in GitHub Desktop.

Select an option

Save rainrisa/1ef61d8f42f16eb942b6e7fefe673112 to your computer and use it in GitHub Desktop.
my simple trilium backup script
#!/usr/bin/env bash
set -euo pipefail
# ─── CONFIG ────────────────────────────────────────────────────────
BACKUP_DIR="$(pwd)"
NOTE_ID=""
SERVER_URL=""
DATA_URL="$SERVER_URL/etapi/notes/$NOTE_ID/export"
SECRET_TOKEN=""
MAX_BACKUPS=5
# ──────────────────────────────────────────────────────────────────
mkdir -p "$BACKUP_DIR"
# 1) Download into a temp file
TMP_ZIP="$(mktemp --suffix=.zip)"
curl -sSL -H "Authorization: $SECRET_TOKEN" "$DATA_URL" -o "$TMP_ZIP"
# 2) Measure size of the new download
NEW_SIZE=$(stat -c '%s' "$TMP_ZIP")
# 3) Find existing backups, sorted oldest first
mapfile -t EXISTING < <(ls -1tr "$BACKUP_DIR"/*.zip 2>/dev/null || true)
if (( ${#EXISTING[@]} > 0 )); then
OLDEST="${EXISTING[0]}"
OLDEST_SIZE=$(stat -c '%s' "$OLDEST")
# 4) If new is smaller than the oldest, skip backup
if (( NEW_SIZE < OLDEST_SIZE )); then
echo "⚠️ New backup ($NEW_SIZE bytes) is smaller than oldest ($OLDEST_SIZE bytes); aborting."
rm -f "$TMP_ZIP"
exit 0
fi
fi
# 5) If at max capacity, delete the oldest before saving
if (( ${#EXISTING[@]} >= MAX_BACKUPS )); then
echo "🗑 Removing oldest backup: $OLDEST"
rm -f "$OLDEST"
fi
# 6) Move temp into a timestamped filename
TIMESTAMP="$(date +%Y.%m.%d)"
DEST="$BACKUP_DIR/backup-$TIMESTAMP.zip"
mv "$TMP_ZIP" "$DEST"
echo "✅ Backup saved: $DEST"
@rainrisa
Copy link
Author

this script will fetch the backup and replace the oldest one whenever the backup file exceed MAX_BACKUPS

example of the crontab script:

0 2 * * 0 cd /home/rain/Documents/trilium-rain-backup; bash script.sh

it will run on sunday at 2:00 AM

also it will not save the backup if the new file size is smaller than the oldest backup file
this is to prevent issues like we accidentally reset our trilium data,
and our script still overriding the older backups even though the new backup have no data at all

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