SFTP Commands Reference - Proper Way to Transfer Files
Complete reference for SFTP operations. No bullshit, just working commands for real file transfer tasks.
SFTP is SSH File Transfer Protocol. It works over SSH tunnel, so everything is encrypted. Much better than old FTP which sends passwords in plain text like amateur hour. If you still use FTP in 2025, you need to reconsider your life choices.
sftp [-46AaCfNpqrv] [-B buffer_size] [-b batchfile] [-c cipher]
[-D sftp_server_path] [-F ssh_config] [-i identity_file]
[-J destination] [-l limit] [-o ssh_option] [-P port]
[-R num_requests] [-S program] [-s subsystem | sftp_server]
destination
Most options you will never need. But good to know they exist.
# Standard connection
sftp username@hostname
# Different port (because admin changed default)
sftp -P 2222 username@hostname
# With SSH key (proper way)
sftp -i ~/.ssh/id_rsa username@hostname
# Force IPv4 (when IPv6 is broken again)
sftp -4 username@hostname
# Force IPv6 (for hipsters)
sftp -6 username@hostname
# Bigger buffer = faster transfer (usually)
sftp -B 32768 username@hostname
# Limit bandwidth so network admin doesn't yell at you
sftp -l 1000 username@hostname
# Run commands from file (for automation)
sftp -b commands.txt username@hostname
# Example batch file (commands.txt):
# cd /remote/path
# get file.txt
# put local.txt
# bye
# Enable compression (good for slow networks)
sftp -C username@hostname
# Choose cipher (if you know what you doing)
sftp -c aes256-ctr username@hostname
# Verbose output (when things go wrong)
sftp -v username@hostname
# Quiet mode (no progress bar noise)
sftp -q username@hostname
# Keep file timestamps (important for backups)
sftp -p username@hostname
# Custom SSH config
sftp -F /path/to/ssh_config username@hostname
# Jump through bastion host
sftp -J jumphost username@destination
# More parallel requests = faster (sometimes)
sftp -R 64 username@hostname
Once connected, use these commands. Very similar to FTP but better.
# List remote files
ls
ls -la
# List local files
lls
lls -la
# Where am I on remote?
pwd
# Where am I locally?
lpwd
# Change remote directory
cd /remote/path
# Change local directory
lcd /local/path
# Download file from server
get remote_file.txt
get remote_file.txt local_file.txt
# Download keeping permissions
get -p remote_file.txt
# Download entire directory
get -r remote_directory/
# Upload file to server
put local_file.txt
put local_file.txt remote_file.txt
# Upload keeping permissions
put -p local_file.txt
# Upload entire directory
put -r local_directory/
# Create directory on server
mkdir remote_directory
# Create local directory
lmkdir local_directory
# Delete remote file
rm remote_file.txt
# Delete remote directory (must be empty)
rmdir remote_directory
# Rename/move files on server
rename old_name.txt new_name.txt
# Fix permissions (very important!)
chmod 644 remote_file.txt
chmod 755 script.sh
# Change ownership
chown user remote_file.txt
chown user:group remote_file.txt
# Change group
chgrp group remote_file.txt
# Check disk space (before uploading big files)
df
df -h
# File information
stat remote_file.txt
# Local file information
lstat local_file.txt
# SFTP version
version
# Run command on remote server
!command
# Run command locally
lcommand
# Show help (when you forget)
help
?
# Exit session
exit
quit
bye
# Download all text files (wildcards work)
sftp> mget *.txt
sftp> mget backup_*.tar.gz
# Upload multiple files
sftp> mput *.log
sftp> mput report_*.pdf
#!/bin/bash
# sftp-upload.sh - Simple upload automation
REMOTE_HOST="example.com"
REMOTE_USER="username"
REMOTE_DIR="/uploads"
LOCAL_FILE="/path/to/file.txt"
sftp -b - ${REMOTE_USER}@${REMOTE_HOST} << EOF
cd ${REMOTE_DIR}
put ${LOCAL_FILE}
bye
EOF
#!/bin/bash
# backup-to-remote.sh - Real backup script
BACKUP_DIR="/var/backups"
REMOTE_HOST="backup.example.com"
REMOTE_USER="backup"
REMOTE_DIR="/backups"
DATE=$(date +%Y%m%d)
BACKUP_FILE="backup_${DATE}.tar.gz"
# Make backup first
tar -czf ${BACKUP_DIR}/${BACKUP_FILE} /path/to/data
# Send to remote server
sftp -i ~/.ssh/backup_key ${REMOTE_USER}@${REMOTE_HOST} << EOF
cd ${REMOTE_DIR}
put ${BACKUP_DIR}/${BACKUP_FILE}
ls -la
bye
EOF
echo "Backup completed: ${BACKUP_FILE}"
#!/bin/bash
# download-latest.sh - Get new reports automatically
REMOTE_HOST="fileserver.example.com"
REMOTE_USER="files"
REMOTE_DIR="/shared/reports"
LOCAL_DIR="/home/user/downloads"
sftp ${REMOTE_USER}@${REMOTE_HOST} << EOF
cd ${REMOTE_DIR}
lcd ${LOCAL_DIR}
mget report_$(date +%Y%m)*.pdf
bye
EOF
# Download everything, keep structure
sftp user@host << EOF
cd /remote/path
lcd /local/path
get -r *
bye
EOF
# Generate modern SSH key
ssh-keygen -t ed25519 -C "sftp-access"
# Install key on server (proper way)
ssh-copy-id -i ~/.ssh/id_ed25519.pub username@hostname
# Connect with key
sftp -i ~/.ssh/id_ed25519 username@hostname
Add this to /etc/ssh/sshd_config to create SFTP-only users:
# Create group for SFTP prisoners
sudo groupadd sftponly
# Add user to jail
sudo usermod -aG sftponly username
# SSH config modification
Match Group sftponly
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
# Use modern cipher
sftp -c [email protected] username@hostname
# Specify multiple ciphers
sftp -o Ciphers=[email protected],aes256-ctr username@hostname
# See what's happening
sftp -v username@hostname
# See everything happening
sftp -vv username@hostname
# Fix SSH key permissions (common problem)
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 700 ~/.ssh
# Test SSH first
ssh -v username@hostname
# Check if server has space
sftp> df -h
# Check file permissions
sftp> ls -la filename
# Try smaller buffer (network problems)
sftp -B 8192 username@hostname
# Bigger buffer for big files
sftp -B 262144 username@hostname
# Compress data (helps on slow links)
sftp -C username@hostname
# More concurrent operations
sftp -R 128 username@hostname
# All optimizations together
sftp -C -B 262144 -R 128 username@hostname
SFTP can resume transfers (unlike some other protocols):
# Resume download
sftp> reget large_file.iso
# Resume upload
sftp> reput large_file.iso
# SCP for quick one-shot transfers
scp file.txt username@hostname:/path/
# SFTP for interactive work
sftp username@hostname
# rsync is better for synchronization
rsync -avz -e ssh /local/path/ username@hostname:/remote/path/
- Always use SSH keys - passwords are for amateurs
- Limit bandwidth with
-lon shared networks - Use batch mode for scripts - no human interaction needed
- Enable compression on slow connections
- Preserve timestamps with
-pfor backups - Test with verbose mode before automation
- Check exit codes in scripts - assume nothing
- Handle errors properly - Murphy’s law applies
- Use chroot jails for untrusted users
- Keep software updated - security matters
SFTP is reliable tool for moving files securely. Learn these commands, use SSH keys properly, and your file transfers will work without drama. Much better than debugging FTP problems or explaining to security team why you sent passwords in cleartext.
Remember: if it works in testing, it will probably work in production. If it doesn’t work in testing, fix it before deployment. This is basic engineering principle.