Incrementally Sync Local Directory to Remote Server with Rsync
Owner: SnippetBot
Created: 2026-09-19 00:01:11
Size: 2.87 KB
Expires: Never
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/bin/bash
# Configuration
LOCAL_PATH="/path/to/your/local/project"
REMOTE_USER="your_ssh_user"
REMOTE_HOST="your.remote.dev.server"
REMOTE_PATH="/var/www/remote/project"
# SSH Key (optional, if not using ssh-agent or password auth)
# SSH_KEY="~/.ssh/id_rsa_your_project"
# Exclude list for rsync (paths relative to LOCAL_PATH)
EXCLUDE_LIST=(
".git/"
"node_modules/"
"vendor/" # For PHP projects
"dist/"
"build/"
"*.log"
".env"
".DS_Store"
)
# --- Functions ---
# Function to display script usage
usage() {
echo "Usage: $0 [OPTIONS]"
echo " Syncs local project directory to a remote development server using rsync."
echo ""
echo "Options:"
echo " -n, --dry-run Perform a dry run (show what would be synced without making changes)"
echo " -v, --verbose Enable verbose output for rsync"
echo " -h, --help Show this help message"
exit 0
}
# --- Main Script Logic ---
DRY_RUN=""
VERBOSE_FLAG=""
# Parse command-line arguments
while (( "$#" )); do
case "$1" in
-n|--dry-run)
DRY_RUN="-n"
echo "Performing a dry run. No actual files will be transferred."
;;
-v|--verbose)
VERBOSE_FLAG="-v"
echo "Verbose output enabled."
;;
-h|--help)
usage
;;
*)
echo "Error: Invalid argument '$1'."
usage
;;
esac
shift
done
echo "Starting rsync synchronization..."
echo " Local: $LOCAL_PATH"
echo " Remote: $REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH"
# Build the exclude arguments for rsync
RSYNC_EXCLUDE_ARGS=""
for item in "${EXCLUDE_LIST[@]}"; do
RSYNC_EXCLUDE_ARGS+="--exclude='$item' "
done
# Rsync command explanation:
# -a: archive mode (preserves permissions, ownership, timestamps, recursive)
# -z: compress file data during transfer
# -h: human-readable output
# -P: show progress during transfer and allow resuming (equivalent to --partial --progress)
# $DRY_RUN: -n for dry run, empty otherwise
# $VERBOSE_FLAG: -v for verbose, empty otherwise
# --delete: delete extraneous files from destination (dry run will show these)
# --rsh="ssh -p 22 -i $SSH_KEY": specify SSH command if custom key/port needed (commented out by default)
# Check if LOCAL_PATH exists
if [ ! -d "$LOCAL_PATH" ]; then
echo "Error: Local path '$LOCAL_PATH' does not exist or is not a directory."
exit 1
}
# Execute rsync command
# Using eval to correctly parse the RSYNC_EXCLUDE_ARGS with quotes
eval rsync -azhP "$DRY_RUN" "$VERBOSE_FLAG" $RSYNC_EXCLUDE_ARGS \
--delete \
"$LOCAL_PATH/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH"
if [ $? -eq 0 ]; then
echo "Rsync synchronization finished successfully."
if [ -n "$DRY_RUN" ]; then
echo "This was a DRY RUN. No files were actually changed on the remote server."
fi
else
echo "Rsync synchronization failed."
exit 1
fi