-
-
Save evanesoteric/85505609b645cb92dc2d2d23f3f35d1a to your computer and use it in GitHub Desktop.
This script backs up a user's home directory to a remote server using rsync.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # ============================================================================== | |
| # REMOTE RSYNC BACKUP SCRIPT | |
| # ============================================================================== | |
| # This script backs up a user's home directory to a remote server using rsync. | |
| # It incorporates file logging, an execution timer, and a configurable port. | |
| # ============================================================================== | |
| # --- Configuration --- | |
| # Set the details for your remote backup server and script options below. | |
| # Remote server SSH user and IP address/hostname | |
| REMOTE_USER="root" | |
| REMOTE_HOST="192.168.0.2" | |
| REMOTE_PORT="22" # Default SSH port. Change to your custom port if needed. | |
| # The base directory on the remote server where backups will be stored. | |
| REMOTE_BASE_DIR="/mnt/Pool0/Backups" | |
| # The source directory to back up on this local machine. | |
| # Default is the current user's home directory. | |
| SOURCE_DIR="${HOME}" | |
| # --- Logging Configuration --- | |
| ENABLE_LOGGING=true | |
| LOG_FILE="${HOME}/remote_backup.log" | |
| # --- Exclude Patterns --- | |
| # List of directories and file patterns to exclude from the backup. | |
| # Paths should be relative to the SOURCE_DIR. | |
| # Add a trailing slash '/' to match a directory specifically. | |
| EXCLUDE_PATTERNS=( | |
| # --- General System/Cache Folders --- | |
| ".cache/" | |
| ".local/share/Trash/" | |
| ".thumbnails/" | |
| # --- Development / Package Manager Caches & Modules --- | |
| "node_modules/" | |
| ".npm/" | |
| ".cargo/" | |
| ".rustup/" | |
| "__pycache__/" | |
| "venv/" | |
| "env/" | |
| ".venv/" | |
| ".env/" | |
| "go/" | |
| ) | |
| # --- Script Logic --- | |
| # (You shouldn't need to edit below this line) | |
| # Exit script on first error and on pipeline error | |
| set -e | |
| set -o pipefail | |
| # Reset BASH time counter | |
| SECONDS=0 | |
| # --- Logging Setup --- | |
| # If logging is enabled, redirect stdout/stderr to both the console and a log file. | |
| if [ "${ENABLE_LOGGING}" = true ]; then | |
| # Create/clear the log file for this run. | |
| : > "${LOG_FILE}" | |
| # Use 'tee' to send output to the log file while also displaying it. | |
| # This redirects both stdout and stderr to the tee command. | |
| exec &> >(tee -a "${LOG_FILE}") | |
| fi | |
| # 1. Set up variables | |
| # ------------------------------------------------------------------------------ | |
| # Get the current username and hostname to create a unique backup directory name. | |
| CURRENT_USER="${USER}" | |
| HOSTNAME=$(hostname) | |
| BACKUP_SUBDIR="${CURRENT_USER}@${HOSTNAME}" | |
| # Construct the full remote destination for rsync. | |
| REMOTE_DEST_RSYNC="${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_BASE_DIR}/${BACKUP_SUBDIR}" | |
| # Construct the path on the remote server for the mkdir command. | |
| REMOTE_DEST_PATH="${REMOTE_BASE_DIR}/${BACKUP_SUBDIR}" | |
| # Define the SSH and rsync remote shell commands with the custom port | |
| SSH_CMD="ssh -p ${REMOTE_PORT}" | |
| RSYNC_RSH="ssh -p ${REMOTE_PORT}" | |
| echo ">>> Starting Backup for: ${BACKUP_SUBDIR}" | |
| echo " Source: ${SOURCE_DIR}" | |
| echo " Destination: ${REMOTE_DEST_RSYNC}" | |
| echo " Port: ${REMOTE_PORT}" | |
| echo "----------------------------------------------------" | |
| # 2. Ensure remote directory exists | |
| # ------------------------------------------------------------------------------ | |
| # Use SSH to create the specific backup directory on the remote server. | |
| # The '-p' flag ensures that parent directories are created if they don't exist. | |
| echo "--> Checking/Creating remote directory..." | |
| ${SSH_CMD} "${REMOTE_USER}@${REMOTE_HOST}" "mkdir -p '${REMOTE_DEST_PATH}'" | |
| if [ $? -ne 0 ]; then | |
| echo "!!! ERROR: Could not create directory on remote server. Aborting." | |
| exit 1 | |
| fi | |
| echo " Remote directory is ready." | |
| # 3. Build rsync command with excludes | |
| # ------------------------------------------------------------------------------ | |
| # This loop dynamically builds the --exclude arguments for the rsync command. | |
| rsync_exclude_opts=() | |
| for pattern in "${EXCLUDE_PATTERNS[@]}"; do | |
| rsync_exclude_opts+=( --exclude="$pattern" ) | |
| done | |
| # 4. Execute the rsync backup | |
| # ------------------------------------------------------------------------------ | |
| # -a: Archive mode (preserves permissions, ownership, timestamps, etc.) | |
| # -v: Verbose mode (shows which files are being transferred). | |
| # -z: Compresses file data during the transfer to save bandwidth. | |
| # --info=progress2: Shows overall transfer progress. | |
| # -e: Specifies the remote shell to use (for setting the port). | |
| # | |
| # NOTE: The --delete flag is NOT used. This means files that you | |
| # delete on your local machine will NOT be deleted from the backup server. | |
| echo "--> Starting file transfer with rsync..." | |
| rsync -avz --info=progress2 -e "${RSYNC_RSH}" \ | |
| "${rsync_exclude_opts[@]}" \ | |
| "${SOURCE_DIR}/" \ | |
| "${REMOTE_DEST_RSYNC}/" | |
| # 5. Final status | |
| # ------------------------------------------------------------------------------ | |
| # Calculate and format the elapsed time. | |
| ELAPSED_TIME="$((SECONDS / 3600))hrs $(((SECONDS / 60) % 60))min $((SECONDS % 60))sec" | |
| echo "----------------------------------------------------" | |
| echo ">>> Backup completed successfully!" | |
| echo " Total Time: ${ELAPSED_TIME}" | |
| if [ "${ENABLE_LOGGING}" = true ]; then | |
| echo " Log file available at: ${LOG_FILE}" | |
| fi | |
| echo "----------------------------------------------------" | |
| exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment