I know there are those who treat any systemd as heresy, but I love systemd timers.
journalctl -u weewx-backup.timer -u weewx-backup.service --since "2026-09-24 00:01:55" --until "2026-09-24 00:02:15" -o short-precise Sep 24 00:02:09.251944 weather systemd[1]: Starting weewx-backup.service - WeeWX Weather Database Backup Service... Sep 24 00:02:09.266633 weather weewx_backup.sh[10032]: === weewx backup starting: Thu Sep 24 12:02:09 AM EDT 2026 === Sep 24 00:02:11.259816 weather weewx_backup.sh[10032]: === weewx backup completed: Thu Sep 24 12:02:11 AM EDT 2026 === Sep 24 00:02:11.265837 weather systemd[1]: weewx-backup.service: Deactivated successfully. Sep 24 00:02:11.265970 weather systemd[1]: Finished weewx-backup.service - WeeWX Weather Database Backup Service. Sep 24 00:02:11.266147 weather systemd[1]: weewx-backup.service: Consumed 451ms CPU time, 77.5M memory peak. On Wednesday, September 23, 2026 at 9:13:04 PM UTC-4 David Schulz wrote: > Thanks Warren for pointing me at the backup function in SQLite itself. At > the moment I have managed to get a simple copy of the database file to a > remote location working, so that is a start. This sounds like a more fault > tolerant approach as the database engine is managing both any potential > writes and the backup process to void conflicts. > > My simple approach is taking seconds to execute, so judicious timing of > the cron job is working for the present. > > Appreciate you taking the time to chime in. As you say, good to have > someone challenging your assumptions rather than just diving deeper down > the rabbit hole you're currently stuck in. > > On Tuesday, September 22, 2026 at 12:59:55 PM UTC+10 Warren Gill wrote: > >> The AI is not "drivel" but it's also not really helpful. AI tends to keep >> leading you down the same incorrect path just to fulfill your instruction. >> SQLite3 has included a backup API since 3.3.0. There's no need to >> stop/start/quiesce just use the .backup command. >> https://www.sqlite.org/backup.html >> Most of this script is error checking stuff I borrowed from my other >> error checking stuff. It really just boils down to: >> >> *sqlite3 /var/lib/weewx/weewx.sdb ".backup /var/tmp/weewx-$(date >> +%Y%m%d)-backup.sdb"* >> >> Here's the whole script nonetheless: >> >> #!/usr/bin/env bash >> set -Eeuo pipefail >> >> # Uses SQLite Online Backup API >> # https://www.sqlite.org/backup.html >> # Logs to journal >> # View the logs with journalctl -t weewx-backup --since "1 hour ago" >> >> # >> # Add to crontab to run daily at 2 AM: >> # MAILTO="[email protected]" >> # 0 2 * * * /usr/bin/env bash /usr/local/bin/weewx-backup.sh >> # >> DB="/var/lib/weewx/weewx.sdb" >> BACKUPDIR="/var/tmp/wxbackups" >> TIMESTAMP="$(date +%Y%m%d-%H%M%S)" >> BACKUP_PATH="${BACKUPDIR}/weewx-${TIMESTAMP}.sdb" >> ARCHIVE_PATH="${BACKUP_PATH}.gz" >> >> mkdir -p "$BACKUPDIR" >> exec 1> >(logger -t weewx-backup) 2>&1 >> >> log() { >> echo "[$(date -Is)] $*" >> } >> >> log "Starting weewx backup" >> >> if [ ! -f "$DB" ]; then >> log "ERROR: database not found: $DB" >> exit 1 >> fi >> >> if ! command -v sqlite3 >/dev/null 2>&1; then >> log "ERROR: sqlite3 is not installed" >> exit 1 >> fi >> >> log "Creating SQLite backup: $BACKUP_PATH" >> if ! sqlite3 "$DB" ".backup '$BACKUP_PATH'"; then >> log "ERROR: SQLite backup failed" >> exit 1 >> fi >> >> log "Checking database integrity" >> if ! sqlite3 "$BACKUP_PATH" "PRAGMA integrity_check;" | grep -qi '^ok$'; >> then >> log "ERROR: backup integrity check failed" >> rm -f "$BACKUP_PATH" >> exit 1 >> fi >> >> log "Compressing backup" >> gzip -9 "$BACKUP_PATH" >> >> log "Removing backups older than 30 days" >> find "$BACKUPDIR" -type f -name 'weewx-*.sdb.gz' -mtime +30 -delete >> >> log "Backup complete: $ARCHIVE_PATH" >> exit 0 >> >> On Monday, September 21, 2026 at 8:47:49 PM UTC-5 Pablo Sanchez wrote: >> >>> I found the Gen AI response on point. >>> >>> What's more disconcerting would be a single person dictating what is and >>> what isn't allowed to be posted to a worldwide list. >>> --- >>> pablo >>> >>> On September 21, 2026 20:55:14 John Bonzey <[email protected]> wrote: >>> >>>> How is it drivel. it gives the completed script with an explanation >>>> >>>> On Monday, September 21, 2026 at 8:51:02 PM UTC-4 Vince Skahan wrote: >>>> >>>>> Please no three page AI drivel. Please. >>>>> >>>>> On Monday, September 21, 2026 at 5:06:31 PM UTC-7 John Bonzey wrote: >>>>> >>>>>> Claude says the following; >>>>>> >>>>>> Subject: Re: bash while loop syntax for weewx backup script >>>>>> >>>>>> Hi, >>>>>> >>>>>> I think I spotted the issue. Your while condition is: >>>>>> >>>>>> while [ systemctl -q is-active weewx ]; >>>>>> >>>>>> The problem is that [ ... ] is the "test" command - it doesn't >>>>>> actually run systemctl at all. It just checks whether the string >>>>>> "systemctl >>>>>> -q is-active weewx" is non-empty, which is always true, so the loop >>>>>> never >>>>>> ends based on weewx's real state (it just happens to work when weewx >>>>>> stops >>>>>> quickly, since the loop body still runs and eventually you get lucky >>>>>> with >>>>>> timing). >>>>>> >>>>>> The fix is to drop the [ ] brackets entirely and use the command >>>>>> itself as the condition. In bash, while just checks the exit status of >>>>>> whatever command you give it - it doesn't need [ ] at all unless you're >>>>>> testing a string, number, or file: >>>>>> >>>>>> while systemctl -q is-active weewx; >>>>>> do >>>>>> sleep 1 >>>>>> echo $(date): Weewx is still stopping >> >>>>>> /var/log/weewx-backup.log >>>>>> done >>>>>> >>>>>> systemctl -q is-active weewx exits 0 (true) while the service is >>>>>> active, and non-zero once it's fully stopped - which is exactly what you >>>>>> want the loop to check. >>>>>> >>>>>> General rule of thumb: use while [ condition ] for string/number/file >>>>>> tests, and while some_command when you want to "loop while this command >>>>>> succeeds." >>>>>> >>>>>> Your instinct not to copy the DB mid-write is exactly right, and this >>>>>> fix makes that work as intended. >>>>>> >>>>>> One more suggestion: it's worth adding a timeout guard in case weewx >>>>>> ever hangs on stop, so the script can't wait forever. Here's the full >>>>>> script with that added: >>>>>> >>>>>> #!/bin/bash >>>>>> # >>>>>> # Stop weewx service >>>>>> echo $(date): Weewx is stopping >> /var/log/weewx-backup.log >>>>>> systemctl stop weewx >>>>>> # >>>>>> # Check service has stopped (with timeout) >>>>>> timeout=30 >>>>>> count=0 >>>>>> while systemctl -q is-active weewx; >>>>>> do >>>>>> if [ $count -ge $timeout ]; then >>>>>> echo $(date): Weewx did not stop after ${timeout}s - >>>>>> aborting backup >> /var/log/weewx-backup.log >>>>>> systemctl start weewx >>>>>> exit 1 >>>>>> fi >>>>>> sleep 1 >>>>>> count=$((count + 1)) >>>>>> echo $(date): Weewx is still stopping >> >>>>>> /var/log/weewx-backup.log >>>>>> done >>>>>> echo $(date): Weewx has stopped >> /var/log/weewx-backup.log >>>>>> # >>>>>> # Copy files to backup folder >>>>>> echo $(date): Backup is starting >> /var/log/weewx-backup.log >>>>>> tar -czvf /mnt/backup/weewx-conf.tar.gz /etc/weewx >>>>>> tar -czvf /mnt/backup/weewx-db.tar.gz /var/lib/weewx/weewx.sdb >>>>>> echo $(date): Backup is complete >> /var/log/weewx-backup.log >>>>>> # >>>>>> # Start weewx service >>>>>> systemctl start weewx >>>>>> echo $(date): Weewx is starting >> /var/log/weewx-backup.log >>>>>> >>>>>> With the timeout added, if weewx ever fails to stop within 30 >>>>>> seconds, the script restarts weewx, logs the failure, and exits before >>>>>> touching the backup files - so a hung stop can't leave weewx down or >>>>>> risk >>>>>> copying a database mid-write. >>>>>> >>>>>> Hope that helps! >>>>>> ------------------------------ >>>>>> *From:* [email protected] <[email protected]> on >>>>>> behalf of David Schulz <[email protected]> >>>>>> *Sent:* Monday, September 21, 2026 7:22 PM >>>>>> *To:* weewx-user <[email protected]> >>>>>> *Subject:* [weewx-user] Assistance with While condition for backup >>>>>> script >>>>>> >>>>>> Hi >>>>>> I'm attempting to write my first bash script to backup weewx. I'm >>>>>> struggling with the syntax of a condition for a while loop that checks >>>>>> if >>>>>> weewx has stopped or is still stopping. >>>>>> >>>>>> I don't really understand the syntax of the example conditions I can >>>>>> find for various tutorials on using while to create a loop. I cannot >>>>>> find >>>>>> anywhere an exact example of using 'systemctl is-active' as the >>>>>> condition >>>>>> for a while loop. >>>>>> >>>>>> Appreciate any feedback from people more learned than I. >>>>>> >>>>>> TIA >>>>>> >>>>>> Here's what I have at the moment. If I run this script when I know >>>>>> weewx won't be writing to the database, the commands to zip the files >>>>>> into >>>>>> the backup directory all work OK. >>>>>> >>>>>> I don't think I want to be copying the database file in the middle of >>>>>> a write. So I have a separate script with the backup section removed >>>>>> just >>>>>> trying to test the stopping, check has stopped and start parts of the >>>>>> script. I've been unsuccessfully futzing around with different >>>>>> condition >>>>>> syntax and actively trying to run it when weewx is active and the stop >>>>>> command will take a while to execute while the weewx main loop >>>>>> completes. >>>>>> But TBH I'm just wandering about in the dark. >>>>>> >>>>>> ``` >>>>>> #!/bin/bash >>>>>> # >>>>>> # Stop weewx service >>>>>> echo $(date): Weewx is stopping >> /var/log/weewx-backup.log >>>>>> systemctl stop weewx >>>>>> # >>>>>> # Check service has stopped >>>>>> while [ systemctl -q is-active weewx ]; >>>>>> do >>>>>> sleep 1 >>>>>> echo $(date): Weewx is still stopping >> >>>>>> /var/log/weewx-backup.log >>>>>> done >>>>>> echo $(date): Weewx has stopped >> /var/log/weewx-backup.log >>>>>> # >>>>>> # Copy files to backup folder >>>>>> echo $(date): Backup is starting >> /var/log/weewx-backup.log >>>>>> tar -czvf /mnt/backup/weewx-conf.tar.gz /etc/weewx >>>>>> tar -czvf /mnt/backup/weewx-db.tar.gz /var/lib/weewx/weewx.sdb >>>>>> echo $(date): Backup is complete >> /var/log/weewx-backup.log >>>>>> # >>>>>> # Start weewx service >>>>>> systemctl start weewx >>>>>> echo $(date): Weewx is starting >> /var/log/weewx-backup.log >>>>>> ``` >>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "weewx-user" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an email to [email protected]. >>>>>> To view this discussion visit >>>>>> https://groups.google.com/d/msgid/weewx-user/df76a922-ace3-44ae-a65a-0a50b6f8fe92n%40googlegroups.com >>>>>> >>>>>> <https://groups.google.com/d/msgid/weewx-user/df76a922-ace3-44ae-a65a-0a50b6f8fe92n%40googlegroups.com?utm_medium=email&utm_source=footer> >>>>>> . >>>>>> >>>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "weewx-user" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> >>> To view this discussion visit >>>> https://groups.google.com/d/msgid/weewx-user/346dd346-60e0-4fc9-8083-ee1c6b58c8dfn%40googlegroups.com >>>> >>>> <https://groups.google.com/d/msgid/weewx-user/346dd346-60e0-4fc9-8083-ee1c6b58c8dfn%40googlegroups.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>> >>> -- You received this message because you are subscribed to the Google Groups "weewx-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/weewx-user/3ee7f9f2-a9be-49bf-9df2-61f9f0dce555n%40googlegroups.com.
