# Node-RED Backup script (BASH & RSYNC)

**URL:** <https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939>\
**Category:** Share Your Projects\
**Created:** [23 December 2020 18:17 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939 "2020-12-23T18:17:44Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [23 December 2020 18:17 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/1 "2020-12-23T18:17:44Z")

</div>

UPDATED: 2021-02-28 - Fixed the script so that it works properly - reminder to self, don't use relative paths when working with CRON!

* * *

Hi again all, on a roll today. 😃

This time I finally got round to writing a backup script so that I don't have to do it by hand. I've usually done this with a remote tool in the past but I wanted some extra cover and something I can run manually as well if I need an extra backup.

The script here is written as a daily rotating backup so there are some things that you might want to do, I've listed some at the end.

You will need to have `rsync` installed but nothing else is needed other than CRON to run on a daily schedule (you could do that from within Node-RED if you wanted to).

However, this version also uses mosquitto\_pub to send notifications on success or failure. Remove if you don't want that. You could instead use CURL to trigger a Node-RED endpoint.

```bash
#! /usr/bin/env bash

# Redirect stdout to syslog - show with: `sudo journalctl -t nrmain-backup`
exec 1> >(logger -t nrmain-backup -p local0.info)
# redirect stderr to syslog
exec 2> >(logger -t nrmain-backup -p local0.err)

# --- SET THESE TO THE CORRECT LOCATIONS --- #
SOURCE_PATH=/home/home/nrmain
DEST_PATH=/home/home/nrmain-backup
# ------------------------------------------ #

STARTDATE=$(date +'%Y-%m-%d %T')

echo " "
echo "Starting daily backup of $SOURCE_PATH/ to $DEST_PATH/ ..."
echo "Rotating snapshots ..."

# Delete oldest daily backup
if [-d $DEST_PATH/daily.7] ; then
    echo " Deleting oldest daily backup $DEST_PATH/daily.7"

    rm -rf $DEST_PATH/daily.7
fi

# Shift all other daily backups ahead one day
for OLD in 6 5 4 3 2 1	; do
	if [-d $DEST_PATH/daily.$OLD] ; then
		NEW=$(($OLD+1))

		echo " Moving $DEST_PATH/daily.$OLD to $DEST_PATH/daily.$NEW"
		
		# Backup last date
		# ISSUE: touch does not support options on synology (busybox) system
		touch $DEST_PATH/.timestamp -r $DEST_PATH/daily.$OLD
		mv $DEST_PATH/daily.$OLD $DEST_PATH/daily.$NEW
		# Restore timestamp
		touch $DEST_PATH/daily.$NEW -r $DEST_PATH/.timestamp

	fi
done

# Copy hardlinked snapshot of level 0 to level 1 (before updating 0 via rsync)
if [-d $DEST_PATH/daily.0] ; then

	echo " Copying hardlinks from $DEST_PATH/daily.0 to $DEST_PATH/daily.1"

	cp -al $DEST_PATH/daily.0 $DEST_PATH/daily.1
fi

echo "Finished rotating snapshots ..."

if ! [-d $DEST_PATH/daily.0] ; then
	mkdir -p $DEST_PATH/daily.0
fi

# Set today's date on the current backup folder
touch $DEST_PATH/daily.0

ENDDATE=$(date --iso-8601=s)

# Back up
echo "Performing rsync backup ..."
rsync --archive --hard-links --delete --delete-excluded \
      --exclude 'node_modules' --exclude 'data/node_modules' \
      $SOURCE_PATH/ $DEST_PATH/daily.0

# Validate return code
# 0 = no error,
# 24 is fine, happens when files are being touched during sync (logs etc)
# all other codes are fatal -- see man (1) rsync
if ! [$? = 24 -o $? = 0] ; then
	echo "Fatal: Node-RED daily backup finished with errors!"
    mosquitto_pub -r -t services/nrmainbackup/daily/fail -m $ENDDATE
else
    echo "Finished Node-RED daily backup, no errors."
    mosquitto_pub -r -t services/nrmainbackup/daily/success -m $ENDDATE
fi

# Sync disks to make sure data is written to disk
sync

#EOF

```

Some things you might want to do differently:

- This version is set up to work with my alternate installer and assumes that you are running Node-RED with a user account. The folder containing node-red is `~/nrmain`, the userDir folder is `~/nrmain/data`. You might want to adjust paths.
- Have more than 7d of backups. Maybe a second script that rotates monthly.

* * *

And as a bonus, here is the monthly script that I'm using:

```bash
#! /usr/bin/env bash

# Monthly backup for node-red

# Redirect stdout to syslog - show with: `sudo journalctl -t nrmain-backup`
exec 1> >(logger -t nrmain-backup -p local0.info)
# redirect stderr to syslog
exec 2> >(logger -t nrmain-backup -p local0.err)

# --- SET THESE TO THE CORRECT LOCATIONS --- #
SOURCE_PATH=/home/home/nrmain
DEST_PATH=/home/home/nrmain-backup
# ------------------------------------------ #

STARTDATE=$(date +'%Y-%m-%d %T')

echo " "
echo "Starting monthly backup of $SOURCE_PATH/ to $DEST_PATH/ ..."
echo "Rotating snapshots ..."

# Delete oldest daily backup
if [-d $DEST_PATH/monthly.12] ; then
    echo "Deleting oldest monthly backup $DEST_PATH/monthly.12"

	rm -rf $DEST_PATH/monthly.12
fi

# Shift all other daily backups ahead one day
for OLD in 11 10 9 8 7 6 5 4 3 2 1	; do
	if [-d $DEST_PATH/monthly.$OLD] ; then
		NEW=$(($OLD+1))

		echo "Moving $DEST_PATH/monthly.$OLD to $DEST_PATH/monthly.$NEW"
		
		# Backup last date
		# ISSUE: touch does not support options on synology (busybox) system
		touch $DEST_PATH/.timestamp -r $DEST_PATH/monthly.$OLD
		mv $DEST_PATH/monthly.$OLD $DEST_PATH/monthly.$NEW
		# Restore timestamp
		touch $DEST_PATH/monthly.$NEW -r $DEST_PATH/.timestamp

	fi
done

# Copy hardlinked snapshot of level 0 to level 1 (before updating 0 via rsync)
if [-d $DEST_PATH/monthly.0] ; then

	echo "Copying hardlinks from $DEST_PATH/monthly.0 to $DEST_PATH/monthly.1"

	cp -al $DEST_PATH/monthly.0 $DEST_PATH/monthly.1
fi

echo "Finished rotating snapshots ..."

if ! [-d $DEST_PATH/monthly.0] ; then
	mkdir -p $DEST_PATH/monthly.0
fi

# Set today's date on the current backup folder
touch $DEST_PATH/monthly.0

ENDDATE=$(date --iso-8601=s)

# Back up
echo "Performing rsync backup ..."
rsync --archive --hard-links --delete --delete-excluded \
      --exclude 'node_modules' --exclude 'data/node_modules' \
      $SOURCE_PATH/ $DEST_PATH/monthly.0

# Validate return code
# 0 = no error,
# 24 is fine, happens when files are being touched during sync (logs etc)
# all other codes are fatal -- see man (1) rsync
if ! [$? = 24 -o $? = 0] ; then
	echo "Fatal: Node-RED monthly backup finished with errors!"
    #curl --insecure -I 'https://localhost:1880/nrnotify'
    mosquitto_pub -r -t services/nrmainbackup/monthly/fail -m $ENDDATE
else
    echo "Finished Node-RED monthly backup, no errors."
    #curl --insecure -I 'https://localhost:1880/nrnotify'
    mosquitto_pub -r -t services/nrmainbackup/monthly/success -m $ENDDATE
fi

# Sync disks to make sure data is written to disk
sync

#EOF

```

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [28 February 2021 15:55 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/2 "2021-02-28T15:55:30Z")

</div>

Hi all, just updated the above backup script with some corrections. Also added the monthly script.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [31 December 2024 19:30 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/3 "2024-12-31T19:30:28Z")

</div>

@TotallyInformation - a few years now since you posted this... but before I install them...  
Are these still your current backup scripts, and are they still working OK for you?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [1 January 2025 02:03 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/4 "2025-01-01T02:03:52Z")

</div>

Hi Paul,

Nope, had no reason to change them at all! They do what I need them to do. I think I might have recovered something once in all that time - Node-RED is just too darned stable! 😄

Just to double-check though, here is the current daily script:

```bash
#! /usr/bin/env bash

# Redirect stdout to syslog -
# show with: `sudo journalctl -t nrmain-backup`
# or `sudo cat /var/log/syslog | grep nrmain-backup`
exec 1> >(logger -t nrmain-backup -p local0.info)
# redirect stderr to syslog
exec 2> >(logger -t nrmain-backup -p local0.err)

# --- SET THESE TO THE CORRECT LOCATIONS --- #
NR_SERVICE_NAME=nrmain
NR_SOURCE_PATH=/home/home/nrmain
NR_DEST_PATH=/home/home/nrmain-backup
# ------------------------------------------ #

STARTDATE=$(date +'%Y-%m-%d %T')

echo " "
echo "Starting daily backup of $NR_SOURCE_PATH/ to $NR_DEST_PATH/ ..."
echo "Rotating snapshots ..."

# Delete oldest daily backup
if [-d $NR_DEST_PATH/daily.7] ; then
    echo " Deleting oldest daily backup $NR_DEST_PATH/daily.7"

    # The slow but understandable way:
    #rm -rf $NR_DEST_PATH/daily.7
    # The faster way (needs an empty folder)
    rsync -rd --delete $NR_DEST_PATH/empty/ $NR_DEST_PATH/daily.7/
fi

# Shift all other daily backups ahead one day
for OLD in 6 5 4 3 2 1 ; do
        if [-d $NR_DEST_PATH/daily.$OLD] ; then
                NEW=$(($OLD+1))

                echo " Moving $NR_DEST_PATH/daily.$OLD to $NR_DEST_PATH/daily.$NEW"

                # Backup last date
                # ISSUE: touch does not support options on synology (busybox) system
                touch $NR_DEST_PATH/.dtimestamp -r $NR_DEST_PATH/daily.$OLD
                mv $NR_DEST_PATH/daily.$OLD $NR_DEST_PATH/daily.$NEW
                # Restore timestamp
                touch $NR_DEST_PATH/daily.$NEW -r $NR_DEST_PATH/.dtimestamp

        fi
done

# Copy hardlinked snapshot of level 0 to level 1 (before updating 0 via rsync)
if [-d $NR_DEST_PATH/daily.0] ; then

        echo " Copying hardlinks from $NR_DEST_PATH/daily.0 to $NR_DEST_PATH/daily.1"

        cp -al $NR_DEST_PATH/daily.0 $NR_DEST_PATH/daily.1
fi

echo "Finished rotating snapshots ..."

if ! [-d $NR_DEST_PATH/daily.0] ; then
        mkdir -p $NR_DEST_PATH/daily.0
fi

# Set today's date on the current backup folder
touch $NR_DEST_PATH/daily.0

ENDDATE=$(date --iso-8601=s)

# Back up
echo "Performing rsync backup ..."
rsync --archive --hard-links --delete --delete-excluded \
      --exclude 'node_modules' --exclude 'data/node_modules' --exclude 'data/externalModules/node_modules' \
      $NR_SOURCE_PATH/ $NR_DEST_PATH/daily.0

# Validate return code
# 0 = no error,
# 24 is fine, happens when files are being touched during sync (logs etc)
# all other codes are fatal -- see man (1) rsync
# You can output the result to MQTT or to a Node-RED http-in endpoint
if ! [$? = 24 -o $? = 0] ; then
        echo "Fatal: Node-RED daily backup finished with errors!"
    #curl --insecure -I 'https://localhost:1880/nrnotify?type=backup&schedule=daily&result=fail'
    mosquitto_pub -r -t services/$NR_SERVICE_NAME/backup/daily/fail -m $ENDDATE
else
    echo "Finished Node-RED daily backup, no errors."
    #curl --insecure -I 'https://localhost:1880/nrnotify?type=backup&schedule=daily&result=success'
    mosquitto_pub -r -t services/$NR_SERVICE_NAME/backup/daily/success -m $ENDDATE
fi

# Sync disks to make sure data is written to disk
sync

#EOF

```

If that is different, let me know and I'll re-share the weekly and monthly scripts.

I should note that I also use the Backup tool on my NAS to make an encrypted backup of the backups and that backup is, itself, further copied to a spare OneDrive. So I have the 2 local copies and a cloud copy.

OneDrive is, of course, ransomware protected.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [1 January 2025 18:11 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/5 "2025-01-01T18:11:23Z")

</div>

It's working for me until it completes `Moving /home/pi/backupDIR/daily.6 to /home/pi/backupDIR/daily.7`.  
If it's run again I get a rsync error??

```auto
: Starting daily backup of /home/pi/.exampledata/ to /home/pi/backupDIR/ ...
: Rotating snapshots ...
: Moving /home/pi/backupDIR/daily.6 to /home/pi/backupDIR/daily.7
: Moving /home/pi/backupDIR/daily.5 to /home/pi/backupDIR/daily.6
: Moving /home/pi/backupDIR/daily.4 to /home/pi/backupDIR/daily.5
: Moving /home/pi/backupDIR/daily.3 to /home/pi/backupDIR/daily.4
: Moving /home/pi/backupDIR/daily.2 to /home/pi/backupDIR/daily.3
: Moving /home/pi/backupDIR/daily.1 to /home/pi/backupDIR/daily.2
: Copying hardlinks from /home/pi/backupDIR/daily.0 to /home/pi/backupDIR/daily.1
: Finished rotating snapshots ...
: Performing rsync backup ...
: Finished Node-RED daily backup, no errors.
:
: Starting daily backup of /home/pi/.exampledata/ to /home/pi/backupDIR/ ...
: Rotating snapshots ...
: Deleting oldest daily backup /home/pi/backupDIR/daily.7
: rsync: [sender] change_dir "/home/pi/backupDIR/empty" failed: No such file or directory (2)
: rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1338) [sender=3.2.7]
: Moving /home/pi/backupDIR/daily.6 to /home/pi/backupDIR/daily.7
: Moving /home/pi/backupDIR/daily.5 to /home/pi/backupDIR/daily.6
: Moving /home/pi/backupDIR/daily.4 to /home/pi/backupDIR/daily.5
: Moving /home/pi/backupDIR/daily.3 to /home/pi/backupDIR/daily.4
: Moving /home/pi/backupDIR/daily.2 to /home/pi/backupDIR/daily.3
: Moving /home/pi/backupDIR/daily.1 to /home/pi/backupDIR/daily.2
: Copying hardlinks from /home/pi/backupDIR/daily.0 to /home/pi/backupDIR/daily.1
: Finished rotating snapshots ...
: Performing rsync backup ...
: Finished Node-RED daily backup, no errors.

```

If I run the script yet again -

```auto
: Starting daily backup of /home/pi/.exampledata/ to /home/pi/backupDIR/ ...
: Rotating snapshots ...
: Deleting oldest daily backup /home/pi/backupDIR/daily.7
: rsync: [sender] change_dir "/home/pi/backupDIR/empty" failed: No such file or directory (2)
: rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1338) [sender=3.2.7]
: Moving /home/pi/backupDIR/daily.6 to /home/pi/backupDIR/daily.7
: mv: cannot move '/home/pi/backupDIR/daily.6' to '/home/pi/backupDIR/daily.7/daily.6': Directory not empty
: Moving /home/pi/backupDIR/daily.5 to /home/pi/backupDIR/daily.6
: Moving /home/pi/backupDIR/daily.4 to /home/pi/backupDIR/daily.5
: Moving /home/pi/backupDIR/daily.3 to /home/pi/backupDIR/daily.4
: Moving /home/pi/backupDIR/daily.2 to /home/pi/backupDIR/daily.3
: Moving /home/pi/backupDIR/daily.1 to /home/pi/backupDIR/daily.2
: Copying hardlinks from /home/pi/backupDIR/daily.0 to /home/pi/backupDIR/daily.1
: Finished rotating snapshots ...
: Performing rsync backup ...
: Finished Node-RED daily backup, no errors.

```

---

<div class="post-metadata">

**Author:** ![Buckskin](https://avatars.discourse-cdn.com/v4/letter/b/b9e5f3/32.png) [@Buckskin](https://discourse.nodered.org/u/Buckskin)\
**Post date:** [1 January 2025 22:24 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/6 "2025-01-01T22:24:48Z")

</div>

Try creating a directory called '`empty`' in `/home/pi/backupDIR/`

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [1 January 2025 22:52 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/7 "2025-01-01T22:52:58Z")

</div>

> [@Buckskin](#):
>
> Try creating a directory called '`empty`'

Hi Jeff, yes that is the issue 👍  
Maybe that needs adding to the script.

Thanks

EDIT

```auto
...
echo "Starting daily backup of $NR_SOURCE_PATH/ to $NR_DEST_PATH/ ..."
echo "Rotating snapshots ..."

mkdir -p "empty"

# Delete oldest daily backup
if [-d $NR_DEST_PATH/daily.7] ; then
...

```

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 January 2025 12:22 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/8 "2025-01-02T12:22:05Z")

</div>

Oops! Thanks guys. 😄

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [2 January 2025 13:47 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/9 "2025-01-02T13:47:21Z")

</div>

Did you consider using `logrotate` rather than manually moving the old backups?  
Not recommending it because I've never tried it, just wondering. 😃

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 January 2025 15:36 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/10 "2025-01-02T15:36:10Z")

</div>

> [@jbudd](#):
>
> Did you consider using `logrotate` rather than manually moving the old backups?

Nope. 😄

I'm aware that something called `logrotate` exists but I've never actively used it.

I'm also not a BASH expert nor particularly an RSYNC one either. The backup scripts were based on other examples on the Internet.

Honestly, they are probably massive overkill for most people. But they work and don't seem to take a lot of resources so they do the job and that's all I need. A week of daily backups, a month of weekly backups and a year of monthly backups.

If I were to do it over, I'd probably simply do a daily backup to NAS and let the NAS's version history take care of the rest. But as I say, it works so there's no incentive to change it.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [4 January 2025 10:11 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/11 "2025-01-04T10:11:31Z")

</div>

Another issue I've found is that because the backup directories are renamed `daily.0` \> `daily.1` etc, they all have the same timestamp, so you can't determine when the backup was created..

I see in the script, an attempt was made to restore the directory timestamps, to their original time using `touch`, but that doesn't seem to be working.

```auto
touch $NR_DEST_PATH/.dtimestamp -r $NR_DEST_PATH/daily.$OLD
mv $NR_DEST_PATH/daily.$OLD $NR_DEST_PATH/daily.$NEW
# Restore timestamp
touch $NR_DEST_PATH/daily.$NEW -r $NR_DEST_PATH/.dtimestamp

```

I've made a few attempts to fix it, but I'm not that familiar with Bash, although I think that `.dtimestamp` never gets the timestamp from `daily.$OLD` as it never changes. (Line 1 of above code).  
Possible because `touch -r` only works with files & not directories?

> **[touch invocation (GNU Coreutils 9.5)](https://www.gnu.org/software/coreutils/manual/html_node/touch-invocation.html#touch-invocation)**
>
> touch invocation (GNU Coreutils 9.5)

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [4 January 2025 10:45 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/12 "2025-01-04T10:45:58Z")

</div>

> [@Paul-Reed](#):
>
> `touch $NR_DEST_PATH/daily.$NEW -r $NR_DEST_PATH/.dtimestamp`

should possible read

```auto
touch $NR_DEST_PATH/daily.$NEW -r $NR_DEST_PATH/.timestamp

```

[edit] depending which script you have copied.

Just tested script and touch seems to work fine on directories here, and all directories are moved with old timestamps.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [4 January 2025 12:04 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/13 "2025-01-04T12:04:47Z")

</div>

> [@E1cid](#):
>
> depending which script you have copied

Ah yes, the script in the first post has;  
`touch $DEST_PATH/monthly.$NEW -r $DEST_PATH/.timestamp`

..but @TotallyInformation's later revision has;  
`touch $NR_DEST_PATH/daily.$NEW -r $NR_DEST_PATH/.dtimestamp`

But even editing to `touch $DEST_PATH/monthly.$NEW -r $DEST_PATH/.timestamp` and running some minutes apart, I get;

```auto
-rwxr-xr-x 1 pi pi 3139 Jan 4 11:58 backupScript.sh
drwxr-xr-x 5 pi pi 4096 Jan 4 03:15 daily.0
drwxr-xr-x 5 pi pi 4096 Jan 4 03:15 daily.1
drwxr-xr-x 5 pi pi 4096 Jan 4 03:15 daily.2
drwxr-xr-x 5 pi pi 4096 Jan 4 03:15 daily.3
drwxr-xr-x 5 pi pi 4096 Jan 4 03:15 daily.4
-rw-r--r-- 1 pi pi 0 Jan 4 03:15 .dtimestamp
drwxr-xr-x 2 pi pi 4096 Jan 4 11:55 empty

```

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [4 January 2025 12:58 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/14 "2025-01-04T12:58:44Z")

</div>

Try tomorrow or change system date.  
On my system only the date is adjusted, the time does not change, if the backup is on same date.

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [4 January 2025 13:05 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/15 "2025-01-04T13:05:26Z")

</div>

> [@E1cid](#):
>
> change system date

```auto
$ date
Sat 4 Jan 13:00:42 GMT 2025

```

...which is correct for here in the UK, but even if the system time was incorrect, it would still increment, but it's still showing 03:15 almost an hour later.

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [4 January 2025 13:11 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/16 "2025-01-04T13:11:54Z")

</div>

I am not saying system time is incorrect  
I am saying  
if you run script on same day all timestamps are the same.  
If you run on a different day the timestamp has a different date and time.

It is a daily script after all.

Moving

```auto
# Set today's date on the current backup folder
touch $NR_DEST_PATH/daily.0

```

to here

```auto
# Back up
echo "Performing rsync backup ..."
rsync --archive --hard-links --delete --delete-excluded \
      --exclude 'node_modules' --exclude 'data/node_modules' --exclude 'data/externalModules/node_modules' \
      $NR_SOURCE_PATH/ $NR_DEST_PATH/daily.0

# Set today's date on the current backup folder
touch $NR_DEST_PATH/daily.0

# Validate return code

```

Sets the correct timestamp to the new backup folder, when backup on same day.

```auto
-rw-------. 1 u0_a102 u0_a102 0 Jan 4 11:23 .dtimestamp
drwx------. 6 u0_a102 u0_a102 4096 Jan 4 14:41 daily.0
drwx------. 6 u0_a102 u0_a102 4096 Jan 4 14:40 daily.1
drwx------. 6 u0_a102 u0_a102 4096 Jan 4 11:23 daily.2
drwx------. 6 u0_a102 u0_a102 4096 Jan 4 11:23 daily.3
drwx------. 6 u0_a102 u0_a102 4096 Jan 4 11:23 daily.4
drwx------. 6 u0_a102 u0_a102 4096 Jan 4 11:23 daily.5
drwx------. 6 u0_a102 u0_a102 4096 Jan 4 11:23 daily.6
drwx------. 3 u0_a102 u0_a102 4096 Jan 4 11:23 daily.7
drwx------. 2 u0_a102 u0_a102 4096 Jan 2 14:25 empty

```

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [4 January 2025 13:12 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/17 "2025-01-04T13:12:35Z")

</div>

This line does indeed set the timestamp on daily.0 to now:  
drwxr-xr-x 5 pi pi 4096 Jan 4 13:06 /home/pi/nodered-backup/daily.0

```auto
# Set today's date on the current backup folder
touch $NR_DEST_PATH/daily.0
ls -ld $NR_DEST_PATH/daily.0 # My insertion

```

But (on my Pi), the rsync command changes it back:

```auto
Performing rsync backup ...
drwxr-xr-x 5 pi pi 4096 Jan 4 10:56 /home/pi/nodered-backup/daily.0

```

And 10:56 is the timestamp of the node-red folder (/home/pi/.node-red)

I'm not too familiar with rsync but it seems to be retaining the timestamp of the files it copies?  
This is contrary to what `man rsync` says since the script is not using -t or --times flag.  
Maybe a Pi does things differently...

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [4 January 2025 16:10 UTC](https://discourse.nodered.org/t/node-red-backup-script-bash-rsync/37939/18 "2025-01-04T16:10:09Z")

</div>

> [@E1cid](#):
>
> Moving
> 
> ```auto
> # Set today's date on the current backup folder
> touch $NR_DEST_PATH/daily.0
> 
> ```

@E1cid Thank you, your edit above resolves the issue 😀  
Now I've got proper timestamps against all of the backups.

```auto
drwxr-xr-x 5 pi pi 4096 Jan 4 16:08 daily.0
drwxr-xr-x 5 pi pi 4096 Jan 4 16:07 daily.1
drwxr-xr-x 5 pi pi 4096 Jan 4 16:06 daily.2
drwxr-xr-x 5 pi pi 4096 Jan 4 16:05 daily.3
drwxr-xr-x 5 pi pi 4096 Jan 4 16:04 daily.4
drwxr-xr-x 5 pi pi 4096 Jan 4 16:03 daily.5
drwxr-xr-x 5 pi pi 4096 Jan 4 16:02 daily.6
drwxr-xr-x 5 pi pi 4096 Jan 4 16:01 daily.7

```

So the full working example is;

```auto
#! /usr/bin/env bash

# Redirect stdout to syslog - show with: `sudo journalctl -t nodered-backup -n 100`
exec 1> >(logger -t nodered-backup -p local0.info)
# redirect stderr to syslog
exec 2> >(logger -t nodered-backup -p local0.err)

# --- SET THESE TO THE CORRECT LOCATIONS --- #
SOURCE_PATH=/home/pi/.node-red
DEST_PATH=/home/pi/backupDIR
# ------------------------------------------ #

STARTDATE=$(date +'%Y-%m-%d %T')

echo " "
echo "Starting daily backup of $SOURCE_PATH/ to $DEST_PATH/ ..."
echo "Rotating snapshots ..."

# Delete oldest daily backup
if [-d $DEST_PATH/daily.7] ; then
    echo " Deleting oldest daily backup $DEST_PATH/daily.7"

    rm -rf $DEST_PATH/daily.7
fi

# Shift all other daily backups ahead one day
for OLD in 6 5 4 3 2 1 ; do
        if [-d $DEST_PATH/daily.$OLD] ; then
                NEW=$(($OLD+1))

                echo " Moving $DEST_PATH/daily.$OLD to $DEST_PATH/daily.$NEW"

                # Backup last date
                # ISSUE: touch does not support options on synology (busybox) system
                touch $DEST_PATH/.timestamp -r $DEST_PATH/daily.$OLD
                mv $DEST_PATH/daily.$OLD $DEST_PATH/daily.$NEW
                # Restore timestamp
                touch $DEST_PATH/daily.$NEW -r $DEST_PATH/.timestamp

        fi
done

# Copy hardlinked snapshot of level 0 to level 1 (before updating 0 via rsync)
if [-d $DEST_PATH/daily.0] ; then

        echo " Copying hardlinks from $DEST_PATH/daily.0 to $DEST_PATH/daily.1"

        cp -al $DEST_PATH/daily.0 $DEST_PATH/daily.1
fi

echo "Finished rotating snapshots ..."

if ! [-d $DEST_PATH/daily.0] ; then
        mkdir -p $DEST_PATH/daily.0
fi

ENDDATE=$(date --iso-8601=s)

# Back up
echo "Performing rsync backup ..."
rsync --archive --hard-links --delete --delete-excluded \
      --exclude 'node_modules' --exclude 'data/node_modules' \
      $SOURCE_PATH/ $DEST_PATH/daily.0

# Set today's date on the current backup folder
touch $DEST_PATH/daily.0

# Validate return code
# 0 = no error,
# 24 is fine, happens when files are being touched during sync (logs etc)
# all other codes are fatal -- see man (1) rsync
if ! [$? = 24 -o $? = 0] ; then
        echo "Fatal: Node-RED daily backup finished with errors!"
    #curl --insecure -I 'https://localhost:1880/nrnotify?type=backup&schedule=daily&result=fail'
    mosquitto_pub -u username -P password -t services/$NR_SERVICE_NAME/backup/daily -m 'backup failed'
else
    echo "Finished Node-RED daily backup, no errors."
    #curl --insecure -I 'https://localhost:1880/nrnotify?type=backup&schedule=daily&result=success'
    mosquitto_pub -u username -P password -t services/$NR_SERVICE_NAME/backup/daily -m 'successful backup'
fi

# Sync disks to make sure data is written to disk
sync

#EOF

```
