How to Exclude Directories or Files When Copying to a Remote Machine
Learn how to exclude specific files and directories when copying to remote servers using rsync and scp commands with practical examples.
You need to copy files to a remote server but skip certain directories like node_modules or .git. Two options:
- rsync - Has built-in exclude support (use this)
- scp - No native exclude, needs workarounds
Rsync is the clear winner here.
Excluding Files or Directories with Rsync
rsync provides powerful exclusion options through the --exclude flag:
Basic Exclusion Syntax
rsync -av --exclude 'pattern' source/ user@remote:/destination/
Common Use Cases
Exclude specific directories:
rsync -av --exclude 'node_modules' --exclude '.git' source/ user@remote:/destination/
Exclude by file patterns:
rsync -av --exclude '*.log' --exclude '*.tmp' source/ user@remote:/destination/
Exclude multiple items:
rsync -av --exclude={'*.log','tmp/','cache/'} source/ user@remote:/destination/
Using exclude files:
Create a .rsync-exclude file with patterns:
*.log
*.tmp
node_modules/
.git/
cache/
Then use:
rsync -av --exclude-from='.rsync-exclude' source/ user@remote:/destination/
Advanced Patterns
| Pattern | Matches | Example |
|---|---|---|
*.txt | All text files | file.txt, readme.txt |
temp* | Files starting with “temp” | temp1, temporary |
**/cache/ | Cache directories anywhere | app/cache/, src/cache/ |
*.{log,tmp} | Multiple extensions | error.log, data.tmp |
Excluding Files with SCP
Excluding Files with SCP
SCP doesn’t have built-in exclusion options like rsync, but you can use bash extended globbing patterns.
Enable Extended Globbing
shopt -s extglob
Exclude Files with Patterns
# Copy everything except .txt files
scp !(*.txt) user@remote:/destination/
# Copy everything except specific directories
scp -r !(node_modules|.git) user@remote:/destination/
# Copy everything except log and temp files
scp !(*.log|*.tmp) user@remote:/destination/
Extended Globbing Patterns
| Pattern | Description | Example |
|---|---|---|
!(pattern) | Matches anything except pattern | !(*.txt) excludes text files |
*(pattern) | Matches zero or more occurrences | *(backup) matches backup files |
+(pattern) | Matches one or more occurrences | +(test*) matches test files |
?(pattern) | Matches zero or one occurrence | ?(config) matches config file |
@(pattern) | Matches exactly one pattern | `@(*.js |
Practical Examples
# Copy only source files (exclude build artifacts)
scp -r !(build|dist|node_modules) user@remote:/app/
# Copy configuration files only
scp @(*.conf|*.json|*.yaml) user@remote:/config/
Recommendation: Use rsync instead of scp for complex exclusion needs, as it’s more reliable and feature-rich.
Quick Comparison: rsync vs scp
| Feature | rsync | scp |
|---|---|---|
| Built-in exclusion | ✅ --exclude | ❌ Requires bash globbing |
| Pattern flexibility | ✅ Very flexible | ⚠️ Limited |
| Resumable transfers | ✅ Yes | ❌ No |
| Incremental sync | ✅ Yes | ❌ No |
| Performance | ✅ Faster for large transfers | ⚠️ Slower |
Bottom line: Use rsync for file exclusion tasks - it’s more powerful and easier to use.