SFTP

Chapter 6 — SFTP

SFTP — SSH File Transfer Protocol — is the standard way to transfer files over an SSH connection. Unlike the old FTP protocol (which sends credentials in plain text and requires a separate data channel), SFTP runs entirely inside the encrypted SSH session. If you can SSH into a machine, you can SFTP into it without any extra configuration.

SFTP is not FTP over SSH. Despite the similar name, SFTP is a completely separate protocol developed as part of SSH2. It has nothing in common with FTP or FTPS — it just happens to do the same job (file transfer) more securely.

Connecting

The sftp command takes the same arguments as ssh and supports all the same options — including aliases from your ~/.ssh/config:

# Standard connection — same syntax as ssh sftp user@hostname # With a non-standard port sftp -P 2222 user@hostname ← note: -P not -p (capital P) # Using a specific key sftp -i ~/.ssh/id_work user@hostname # Using a config alias (works exactly like ssh) sftp server sftp pi sftp work
philip@laptop — connecting with sftp
philip@laptop:~$ sftp server Connected to server. sftp> ← you are now in the sftp prompt

Navigating — Local and Remote at the Same Time

The SFTP shell manages two locations simultaneously: one on the remote machine and one on your local machine. Most commands come in pairs — the plain version acts on the remote side, and the version prefixed with l acts locally.

sftp — navigating remote and local directories
# Remote side — where you are on the server sftp> pwd Remote working directory: /home/philip sftp> ls Desktop Documents Downloads projects www sftp> cd www/html sftp> ls -la drwxr-xr-x 2 philip www-data 4096 Jun 15 10:22 . -rw-r--r-- 1 philip www-data 2048 Jun 15 10:22 index.html # Local side — where you are on YOUR machine sftp> lpwd Local working directory: /home/philip sftp> lcd ~/projects/website sftp> lls index.html style.css app.js images/

Uploading and Downloading

Uploading to the server (put)

sftp — uploading files
# Upload a single file to the current remote directory sftp> put index.html Uploading index.html to /var/www/html/index.html index.html 100% 48KB 240.0KB/s 00:00 # Upload to a specific remote path sftp> put style.css /var/www/html/css/style.css # Upload an entire directory recursively sftp> put -r images/ Uploading images/ to /var/www/html/images images/logo.png 100% 128KB 512.0KB/s 00:00 images/hero.jpg 100% 384KB 768.0KB/s 00:00 # Upload multiple files using a glob pattern sftp> put *.html

Downloading from the server (get)

sftp — downloading files
# Download a file to current local directory sftp> get backup.tar.gz Fetching /home/philip/backup.tar.gz to backup.tar.gz backup.tar.gz 100% 1.2GB 4.8MB/s 04:12 # Download to a specific local path sftp> get nginx.conf ~/backups/nginx.conf.bak # Download an entire directory recursively sftp> get -r /var/log/nginx/ ~/logs/nginx/ # Download multiple files with glob sftp> get /var/log/nginx/access.log.*

Managing Files and Directories

sftp — file and directory operations
# Create a directory on the remote server sftp> mkdir uploads sftp> mkdir -p archives/2026/june # Remove a remote file sftp> rm oldfile.html # Remove a remote directory (must be empty) sftp> rmdir old_uploads # Rename / move a remote file sftp> rename draft.html index.html # Check permissions and ownership sftp> ls -la # Change permissions on a remote file sftp> chmod 644 index.html sftp> chmod 755 scripts/deploy.sh # Create a local directory without leaving sftp sftp> lmkdir ~/downloads/server-backup # Run a local shell command with ! sftp> !ls -la ~/downloads/ sftp> !tar -tzf backup.tar.gz | head

Full Command Reference

Command Local equivalent What it does Example
pwd remote lpwd Print current working directory pwd
ls remote lls List directory contents (accepts flags: -la, -lh) ls -la /var/www
cd remote lcd Change directory cd /var/www/html
mkdir remote lmkdir Create a directory mkdir uploads
put local→remote Upload file(s). -r for recursive put -r dist/
get remote→local Download file(s). -r for recursive get -r /var/log/
rm remote Delete a remote file rm old.html
rmdir remote Remove an empty remote directory rmdir tmp
rename remote Rename or move a remote file rename draft.html index.html
chmod remote Change remote file permissions chmod 644 file.php
chown remote Change remote file ownership (numeric UID) chown 1000 file.txt
df remote Show remote disk space usage df
! local Run a local shell command without leaving sftp !ls ~/downloads
help Print all available sftp commands help
bye / quit / exit Close the SFTP session bye

Batch Mode — Non-Interactive Transfers

For scripted or automated transfers, SFTP can read commands from a file with -b, avoiding the need for an interactive session. Combine with -q to suppress progress output:

# Create a batch file — one sftp command per line # ~/deploy.sftp lcd ~/projects/website/dist cd /var/www/html put index.html put style.css put -r assets/ bye
philip@laptop — running an sftp batch file
# -b batch_file runs commands non-interactively philip@laptop:~$ sftp -b ~/deploy.sftp server Uploading index.html to /var/www/html/index.html Uploading style.css to /var/www/html/style.css Uploading assets/ to /var/www/html/assets # -q = quiet: suppress progress output, errors still show philip@laptop:~$ sftp -q -b ~/deploy.sftp server philip@laptop:~$ ← silent unless something fails # Embed in a shell script for a deploy pipeline philip@laptop:~$ npm run build && sftp -q -b ~/deploy.sftp server
Batch mode aborts on the first error. If a put fails (file not found, permission denied), SFTP stops and exits with a non-zero code. For more resilient deploys where you want to continue after errors, consider rsync instead — covered in the next two chapters.

One-Shot Transfers Without an Interactive Session

You can use scp for simple one-file transfers where the interactive SFTP shell would be overkill. But SFTP can do the same thing non-interactively too:

# Upload a single file inline without entering the sftp shell sftp server:/var/www/html/index.html <<< "" ← download trick (rarely used) # The common one-liner for a single upload: still easiest with scp scp index.html server:/var/www/html/ scp -r dist/ server:/var/www/html/ scp -P 2222 file.txt server:~/ ← capital P for port, same as sftp

SFTP vs SCP — Which to Use

SFTP — use when
  • You need to browse the remote filesystem
  • Uploading multiple files interactively
  • You need to rename, move, or delete remote files
  • Batch mode scripted deploys
  • GUI clients (FileZilla, WinSCP use SFTP)
SCP — use when
  • Quick one-shot copy of a known file or directory
  • You already know the exact remote path
  • Copying between two remote machines
    scp server1:file.txt server2:~/
  • Simple scripts where rsync would be overkill
For anything beyond a one-off copy, use rsync instead of either. rsync only transfers what changed, can resume interrupted transfers, and is far more efficient for directories. SFTP and SCP transfer everything every time. Chapters 7 and 8 cover rsync in detail.

GUI Clients

If you prefer a drag-and-drop interface to the command line, several excellent SFTP GUI clients are available. All of them connect using the same credentials and key files as the sftp command.

FileZilla
Windows · macOS · Linux — Free
The most widely used SFTP client. Two-panel layout (local left, remote right) with drag-and-drop. Import your private key via Edit → Settings → Connection → SFTP → Add key file. Set Protocol to "SFTP – SSH File Transfer Protocol" in the Site Manager.
Tip: Use Site Manager (File menu) to save named connections — it remembers port, user, and key path.
WinSCP
Windows only — Free & open source
Windows-native SFTP/SCP client with deep Windows Explorer integration. Can save sessions, run scripts, and sync folders. Supports PuTTY .ppk key files natively — convert OpenSSH keys with PuTTYgen if needed.
Tip: WinSCP can open a PuTTY terminal in the same session via the Open Terminal button.
Cyberduck
Windows · macOS — Free (donation)
Clean, minimal SFTP client that also supports S3, Google Drive, Backblaze, and more. Good choice if you work with multiple storage providers alongside SFTP. Integrates with the macOS keychain for key passphrase storage.
Tip: Right-click any bookmark → Edit → SSH Private Key to point it at your existing key file.
VS Code — Remote SSH
Windows · macOS · Linux — Free
Not a classic SFTP client, but the Remote-SSH extension lets you open a remote directory in VS Code and edit files directly on the server. Saves the upload/download step entirely for editing workflows. Uses your ~/.ssh/config aliases automatically.
Tip: Install "Remote - SSH" from the Extensions panel. Press F1 → "Remote-SSH: Connect to Host" and pick your config alias.

Practical Workflow — Deploying a Website

philip@laptop — full deploy workflow with sftp
# 1. Build the project locally philip@laptop:~$ cd ~/projects/website && npm run build ✓ Build complete → dist/ # 2. Connect to the server with sftp philip@laptop:~$ sftp server Connected to server. # 3. Navigate remote and local directories sftp> cd /var/www/html sftp> lcd ~/projects/website/dist # 4. Upload changed files sftp> put index.html index.html 100% 12KB 240.0KB/s 00:00 sftp> put -r assets/ assets/style.css 100% 24KB 480.0KB/s 00:00 assets/app.js 100% 88KB 880.0KB/s 00:00 # 5. Verify permissions and exit sftp> ls -la sftp> bye philip@laptop:~$
Tab completion works in sftp — press Tab to autocomplete remote paths and filenames just like in your regular shell. A lifesaver when navigating deeply nested directories.

Quick Reference

TaskCommand
Connect using a config aliassftp server
Connect to a non-standard portsftp -P 2222 user@host
Upload a fileput file.html
Upload a directory recursivelyput -r dist/
Download a fileget backup.tar.gz
Download a directory recursivelyget -r /var/log/nginx/
Change remote directorycd /var/www/html
Change local directorylcd ~/projects/dist
Create remote directorymkdir uploads
Delete remote filerm old.html
Rename remote filerename draft.html index.html
Run local command from sftp!ls ~/downloads
Batch/scripted transfersftp -b commands.sftp server
Quick single-file copy (scp)scp file.txt server:~/
Exitbye
Next — Chapter 7: rsync Basics. SFTP transfers whole files every time. rsync is smarter — it compares source and destination and only sends what changed. Chapter 7 covers how rsync works, local directory syncing, and the essential flags you'll use in every rsync command: -a, -v, -z, --delete, and --dry-run.