/commands/rsync/rsync-ssh-port
rsync -e 'ssh -p 2222': rsync over SSH on a custom port or key
- tool
- rsync
- versions
- rsync 3.x, OpenSSH 7.x+
- os
- linux, macos
rsync -av -e 'ssh -p 2222' ./site/ user@server.example.com:/var/www/site/ copies over SSH to a server whose sshd listens on port 2222. -e (--rsh) sets the remote shell command, so any ssh option fits inside the quotes: a key with -i ~/.ssh/deploy_ed25519, a jump host with -J bastion, or -o StrictHostKeyChecking=accept-new. The command must be one argument for rsync, which is why it is quoted. For a server you use often, put the port and key in ~/.ssh/config and use the host alias instead.
Commands
# Custom port
rsync -av -e 'ssh -p 2222' ./site/ deploy@server.example.com:/var/www/site/
# Custom port and key
rsync -av -e 'ssh -p 2222 -i ~/.ssh/deploy_ed25519' ./site/ deploy@server.example.com:/var/www/site/
# Through a jump host
rsync -av -e 'ssh -J admin@bastion.example.com' ./backup/ deploy@10.0.0.5:/srv/backup/
# Pull from the server instead of pushing
rsync -av -e 'ssh -p 2222' deploy@server.example.com:/var/log/app/ ./logs/server.example.com, deploy and the paths stand for your own host, user and directories.
Using ~/.ssh/config instead
Host web1
HostName server.example.com
Port 2222
User deploy
IdentityFile ~/.ssh/deploy_ed25519With that block, rsync -av ./site/ web1:/var/www/site/ uses the port, user and key automatically, and so do ssh web1 and scp. This keeps long -e strings out of scripts and makes the connection easy to test with ssh web1 alone.
Ways to pass ssh options
| Form | Notes |
|---|---|
| -e 'ssh -p 2222' | Port for this command only |
| --rsh='ssh -p 2222' | Long form of -e |
| RSYNC_RSH='ssh -p 2222' rsync ... | Environment variable, used when -e is absent |
| Host block in ~/.ssh/config | Port, user, key and options per host, for every ssh-based tool |
| -e 'ssh -o ConnectTimeout=10' | Any ssh -o option |
| rsync://host:8873/module/ | Daemon mode on a custom port; no ssh involved |
Errors you may see
ssh: connect to host server.example.com port 22: Connection refusedfollowed byrsync: connection unexpectedly closedandrsync error: ... (code 12)or(code 255): the port was not passed, so ssh used 22. Check the-equoting.Permission denied (publickey): the key in-iorIdentityFileis not accepted by the server; test withssh -p 2222 -i KEY user@hostfirst.bash: rsync: command not found(or similar from the remote shell): rsync must be installed on both machines, because ssh starts a second rsync on the server.Host key verification failed: the server's key is not inknown_hostsyet, or it changed. Connect once with plain ssh to check and accept it.
Test the connection first
ssh -p 2222 deploy@server.example.com 'rsync --version' confirms in one step that the port, the key and the remote rsync work. Then run the rsync command with -n to preview the transfer. rsync is available on Linux and macOS; on Windows run it in WSL or Cygwin, where ~/.ssh/config is the one of that environment.
FAQ
Can I write the port in the rsync path, like host:2222:/path?
No. In host:path the part after the colon is the path, so host:2222:/srv is read as the path 2222:/srv. The port goes into the ssh command with -e 'ssh -p 2222', or into ~/.ssh/config. The rsync://host:port/ syntax is only for rsync daemons, not ssh.
What is the --port option of rsync for?
--port sets the TCP port of an rsync daemon (default 873) when you connect with host::module or rsync://. It has no effect on ssh connections.
How do I avoid typing -e every time?
Add a Host block to ~/.ssh/config with HostName, Port, User and IdentityFile, then use the alias, rsync -av src/ myserver:/srv/. Or export RSYNC_RSH='ssh -p 2222', which rsync uses when -e is not given.