---
title: "How to Exclude Directories or Files When Copying to a Remote Machine"
description: "Learn how to exclude specific files and directories when copying to remote servers using rsync and scp commands with practical examples."
date: 2025-07-20
categories: ["vps"]
tags: ["linux-commands"]
---

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
```shell
rsync -av --exclude 'pattern' source/ user@remote:/destination/
```

### Common Use Cases

**Exclude specific directories:**
```shell
rsync -av --exclude 'node_modules' --exclude '.git' source/ user@remote:/destination/
```

**Exclude by file patterns:**
```shell
rsync -av --exclude '*.log' --exclude '*.tmp' source/ user@remote:/destination/
```

**Exclude multiple items:**
```shell
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:
```shell
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
```shell
shopt -s extglob
```

### Exclude Files with Patterns
```shell
# 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|*.css)` matches JS or CSS |

### Practical Examples
```shell
# 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.